Changeset 32490deb
- Timestamp:
- Jan 31, 2024, 6:40:25 PM (21 months ago)
- Branches:
- master
- Children:
- 496ffc17
- Parents:
- c75b30a (diff), e71b09a (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - Files:
-
- 22 edited
Legend:
- Unmodified
- Added
- Removed
-
doc/LaTeXmacros/common.sty
rc75b30a r32490deb 11 11 %% Created On : Sat Apr 9 10:06:17 2016 12 12 %% Last Modified By : Peter A. Buhr 13 %% Last Modified On : Sun Jan 14 12:28:26202414 %% Update Count : 63 113 %% Last Modified On : Sun Jan 21 13:17:48 2024 14 %% Update Count : 633 15 15 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 16 16 … … 270 270 \newlength{\gcolumnposn} % temporary hack because lstlisting does not handle tabs correctly 271 271 \newlength{\columnposn} 272 \setlength{\gcolumnposn}{ 2.75in}272 \setlength{\gcolumnposn}{3in} 273 273 \setlength{\columnposn}{\gcolumnposn} 274 274 \newcommand{\setgcolumn}[1]{\global\gcolumnposn=#1\global\columnposn=\gcolumnposn} -
doc/LaTeXmacros/common.tex
rc75b30a r32490deb 11 11 %% Created On : Sat Apr 9 10:06:17 2016 12 12 %% Last Modified By : Peter A. Buhr 13 %% Last Modified On : Sun Jan 14 17:59:02202414 %% Update Count : 59 213 %% Last Modified On : Wed Jan 24 08:43:57 2024 14 %% Update Count : 593 15 15 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 16 16 … … 273 273 \newlength{\gcolumnposn} % temporary hack because lstlisting does not handle tabs correctly 274 274 \newlength{\columnposn} 275 \setlength{\gcolumnposn}{ 2.75in}275 \setlength{\gcolumnposn}{3in} 276 276 \setlength{\columnposn}{\gcolumnposn} 277 277 \newcommand{\setgcolumn}[1]{\global\gcolumnposn=#1\global\columnposn=\gcolumnposn} -
doc/bibliography/pl.bib
rc75b30a r32490deb 219 219 title = {Actor Benchmarks}, 220 220 author = {Peter A. Buhr and Colby A. Parsons}, 221 howpublished= {\ href{https://github.com/pabuhr/ActorExperiments}{https://\-github.com/\-pabuhr/\-ActorExperiments}},221 howpublished= {\url{https://github.com/pabuhr/ActorExperiments}}, 222 222 year = 2022, 223 223 } … … 296 296 contributer = {pabuhr@plg}, 297 297 author = {Ada16}, 298 title = {Ada Reference Manual 298 title = {Ada Reference Manual ISO/IEC 8652:2012(E) with COR.1:2016}, 299 299 edition = {3rd with Technical Corrigendum 1 for Ada 2012}, 300 300 organization= {AXE Consultants}, … … 416 416 address = {Waterloo, Ontario, Canada, N2L 3G1}, 417 417 optnote = {\textsf{http://uwspace.uwaterloo.ca/\-bitstream/10012/\-5751\-/1/Krischer\_Roy.pdf}}, 418 note = {\ href{http://uwspace.uwaterloo.ca/bitstream/10012/5751/1/Krischer_Roy.pdf}{http://uwspace.uwaterloo.ca/\-bitstream/10012/\-5751\-/1/Krischer\_Roy.pdf}},418 note = {\url{http://uwspace.uwaterloo.ca/bitstream/10012/5751/1/Krischer_Roy.pdf}}, 419 419 } 420 420 … … 430 430 number = 5, 431 431 pages = {1005-1042}, 432 optnote = {\ href{https://onlinelibrary.wiley.com/doi/10.1002/spe.2925}{https://\-onlinelibrary.wiley.com/\-doi/\-10.1002/\-spe.2925}},432 optnote = {\url{https://onlinelibrary.wiley.com/doi/10.1002/spe.2925}}, 433 433 } 434 434 … … 761 761 pages = {145-160}, 762 762 publisher = {{USENIX} Association}, 763 note = {\ href{https://www.usenix.org/conference/osdi18/presentation/qin}{https://\-www.usenix.org/\-conference/\-osdi18/\-presentation/\-qin}},763 note = {\url{https://www.usenix.org/conference/osdi18/presentation/qin}}, 764 764 } 765 765 … … 839 839 title = {Async Await}, 840 840 author = {{WikipediA}}, 841 howpublished= {\ href{https://en.wikipedia.org/wiki/Async/await}{https://\-en.wikipedia.org/\-wiki/\-Async/\-await}},841 howpublished= {\url{https://en.wikipedia.org/wiki/Async/await}}, 842 842 year = 2022, 843 843 } … … 928 928 institution = {Carnegie Mellon University}, 929 929 address = {California Institute of Technology, Pasadena, CA, USA}, 930 note = {\ href{http://www.cs.cmu.edu/~acw/15740/paper.pdf}{http://\-www.cs.cmu.edu/\-$\sim$acw/\-15740/\-paper.pdf}, Accessed May 2014},930 note = {\url{http://www.cs.cmu.edu/~acw/15740/paper.pdf}}, 931 931 year = 2009, 932 932 } … … 1034 1034 title = {Boost Coroutine Library}, 1035 1035 year = 2015, 1036 howpublished= {\href{http://www.boost.org/doc/libs/1_61_0/libs/coroutine/doc/html/index.html} 1037 {http://www.boost.org/\-doc/\-libs/1\_61\_0/\-libs/\-coroutine/\-doc/\-html/\-index.html}}, 1036 howpublished= {\url{http://www.boost.org/doc/libs/1_61_0/libs/coroutine/doc/html/index.html}}, 1038 1037 } 1039 1038 … … 1044 1043 title = {Boost Thread Library}, 1045 1044 year = 2015, 1046 howpublished= {\href{https://www.boost.org/doc/libs/1_61_0/doc/html/thread.html} 1047 {https://\-www.boost.org/\-doc/\-libs/\-1\_61\_0/\-doc/\-html/\-thread.html}}, 1045 howpublished= {\url{https://www.boost.org/doc/libs/1_61_0/doc/html/thread.html}}, 1048 1046 } 1049 1047 … … 1056 1054 month = oct, 1057 1055 type = {Diplomarbeit}, 1058 note = {\ href{https://plg.uwaterloo.ca/~usystem/theses/KrischerThesis.pdf}{https://\-plg.uwaterloo.ca/\-$\sim$usystem/\-theses/\-KrischerThesis.pdf}},1056 note = {\url{https://plg.uwaterloo.ca/~usystem/theses/KrischerThesis.pdf}}, 1059 1057 } 1060 1058 … … 1148 1146 address = {Geneva, Switzerland}, 1149 1147 year = 1999, 1150 note = {\ href{https://webstore.ansi.org/Standards/INCITS/INCITSISOIEC98991999R2005}{https://webstore.ansi.org/\-Standards/\-INCITS/\-INCITSISOIEC98991999R2005}},1148 note = {\url{https://webstore.ansi.org/Standards/INCITS/INCITSISOIEC98991999R2005}}, 1151 1149 } 1152 1150 … … 1160 1158 address = {Geneva, Switzerland}, 1161 1159 year = 2012, 1162 note = {\ href{https://www.iso.org/standard/57853.html}{https://\-www.iso.org/\-standard/\-57853.html}},1160 note = {\url{https://www.iso.org/standard/57853.html}}, 1163 1161 } 1164 1162 … … 1171 1169 address = {Geneva, Switzerland}, 1172 1170 year = 2015, 1173 note = {\ href{https://www.iso.org/standard/64031.html}{https://\-www.iso.org/\-standard/\-64031.html}},1171 note = {\url{https://www.iso.org/standard/64031.html}}, 1174 1172 } 1175 1173 … … 1198 1196 month = aug, 1199 1197 year = {2020}, 1200 note = {\ href{https://cforall.uwaterloo.ca/doc/Fangren_Yu_Report_S20.pdf}{https://\-cforall.uwaterloo.ca/\-doc/\-Fangren\_Yu\_Report\_S20.pdf}},1198 note = {\url{https://cforall.uwaterloo.ca/doc/Fangren_Yu_Report_S20.pdf}}, 1201 1199 } 1202 1200 … … 1212 1210 year = 2018, 1213 1211 pages = {2111-2146}, 1214 optnote = {\ href{http://dx.doi.org/10.1002/spe.2624}{http://\-dx.doi.org/\-10.1002/\-spe.2624}},1212 optnote = {\url{http://dx.doi.org/10.1002/spe.2624}}, 1215 1213 } 1216 1214 … … 1219 1217 key = {Cforall Benchmarks}, 1220 1218 author = {{\textsf{C}{$\mathbf{\forall}$} Benchmarks}}, 1221 howpublished= {\ href{https://github.com/cforall/ConcurrentBenchmarks_SPE20}{https://\-github.com/\-cforall/\-ConcurrentBenchmarks\_SPE20}},1219 howpublished= {\url{https://github.com/cforall/ConcurrentBenchmarks_SPE20}}, 1222 1220 } 1223 1221 … … 1226 1224 key = {Cforall}, 1227 1225 author = {{\textsf{C}{$\mathbf{\forall}$} Features}}, 1228 howpublished= {\ href{https://plg.uwaterloo.ca/~cforall/features}{https://\-plg.uwaterloo.ca/\-$\sim$cforall/\-features}},1226 howpublished= {\url{https://plg.uwaterloo.ca/~cforall/features}}, 1229 1227 } 1230 1228 … … 1245 1243 title = {\textsf{C}$\mathbf{\forall}$ Stack Evaluation Programs}, 1246 1244 year = 2018, 1247 howpublished= {\ href{https://cforall.uwaterloo.ca/CFAStackEvaluation.zip}{https://cforall.uwaterloo.ca/\-CFAStackEvaluation.zip}},1245 howpublished= {\url{https://cforall.uwaterloo.ca/CFAStackEvaluation.zip}}, 1248 1246 } 1249 1247 … … 1256 1254 year = 2004, 1257 1255 address = {Waterloo, Ontario, Canada, N2L 3G1}, 1258 note = {\ href{http://plg.uwaterloo.ca/theses/EstevesThesis.pdf}{http://\-plg.uwaterloo.ca/\-theses/\-EstevesThesis.pdf}},1256 note = {\url{http://plg.uwaterloo.ca/theses/EstevesThesis.pdf}}, 1259 1257 } 1260 1258 … … 1266 1264 year = 2019, 1267 1265 optaddress = {Waterloo, Ontario, Canada, N2L 3G1}, 1268 note = {\ href{https://uwspace.uwaterloo.ca/handle/10012/14584}{https://\-uwspace.uwaterloo.ca/\-handle/\-10012/\-14584}},1266 note = {\url{https://uwspace.uwaterloo.ca/handle/10012/14584}}, 1269 1267 } 1270 1268 … … 1423 1421 month = oct, 1424 1422 year = 2001, 1425 note = {\ href{http://plg.uwaterloo.ca/~cforall/cfa.ps}{http://\-plg.uwaterloo.ca/\-$\sim$cforall/\-cfa.ps}},1423 note = {\url{http://plg.uwaterloo.ca/~cforall/cfa.ps}}, 1426 1424 } 1427 1425 … … 1461 1459 contributer = {a3moss@uwaterloo.ca}, 1462 1460 title = {Clang: a {C} language family frontend for {LLVM}}, 1463 howpublished= {\ href{https://clang.llvm.org/}{https://\-clang.llvm.org/}}1461 howpublished= {\url{https://clang.llvm.org/}} 1464 1462 } 1465 1463 … … 1527 1525 address = {Geneva, Switzerland}, 1528 1526 year = 2014, 1529 note = {\ href{https://www.iso.org/standard/51416.html}{https://\-www.iso.org/\-standard/\-51416.html}},1527 note = {\url{https://www.iso.org/standard/51416.html}}, 1530 1528 } 1531 1529 … … 1668 1666 publisher = {Prentice-Hall}, 1669 1667 address = {Upper Saddle River, NJ, USA}, 1670 note = {\ href{http://www.usingcsp.com/cspbook.pdf}{http://\-www.usingcsp.com/\-cspbook.pdf}},1668 note = {\url{http://www.usingcsp.com/cspbook.pdf}}, 1671 1669 } 1672 1670 … … 1733 1731 month = sep, 1734 1732 address = {Waterloo, Ontario, Canada, N2L 3G1}, 1735 note = {\ href{http://plg.uwaterloo.ca/theses/MokThesis.pdf}{http://\-plg.uwaterloo.ca/\-theses/\-MokThesis.pdf}},1733 note = {\url{http://plg.uwaterloo.ca/theses/MokThesis.pdf}}, 1736 1734 } 1737 1735 … … 1808 1806 author = {Peter A. Buhr and David Dice and Wim H. Hesselink}, 1809 1807 title = {concurrent-locking}, 1810 howpublished= {\ href{https://github.com/pabuhr/concurrent-locking}{https://\-github.com/\-pabuhr/\-concurrent-locking}},1808 howpublished= {\url{https://github.com/pabuhr/concurrent-locking}}, 1811 1809 } 1812 1810 … … 1958 1956 year = 2015, 1959 1957 optaddress = {Waterloo, Ontario, Canada, N2L 3G1}, 1960 note = {\ href{https://uwspace.uwaterloo.ca/handle/10012/10013}{https://\-uwspace.uwaterloo.ca/\-handle/\-10012/\-10013}},1958 note = {\url{https://uwspace.uwaterloo.ca/handle/10012/10013}}, 1961 1959 } 1962 1960 … … 2098 2096 month = oct, 2099 2097 year = 2010, 2100 howpublished= {\href{https://www.airs.com/blog/archives/428} 2101 {https://www.airs.com/\-blog/\-archives/\-428}}, 2098 howpublished= {\url{https://www.airs.com/blog/archives/428}}, 2102 2099 } 2103 2100 … … 2110 2107 year = 1992, 2111 2108 address = {Waterloo, Ontario, Canada, N2L 3G1}, 2112 note = {\ href{http://plg.uwaterloo.ca/theses/DitchfieldThesis.pdf}{http://\-plg.uwaterloo.ca/\-theses/\-DitchfieldThesis.pdf}}2109 note = {\url{http://plg.uwaterloo.ca/theses/DitchfieldThesis.pdf}} 2113 2110 } 2114 2111 … … 2180 2177 author = {Glen Ditchfield}, 2181 2178 title = {Conversions for \textsf{C}$\mathbf{\forall}$}, 2182 note = {\ href{http://plg.uwaterloo.ca/~cforall/Conversions/index.html}{http://\-plg.uwaterloo.ca/\-$\sim$cforall/\-Conversions/\-index.html}},2179 note = {\url{http://plg.uwaterloo.ca/~cforall/Conversions/index.html}}, 2183 2180 month = {Nov}, 2184 2181 year = {2002}, … … 2217 2214 year = 2019, 2218 2215 month = feb, 2219 howpublished= {\href{http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p0912r5.html} 2220 {http://\-www.open-std.org/\-jtc1/\-sc22/\-wg21/\-docs/\-papers/\-2019/p0912r5.html}}, 2216 howpublished= {\url{http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p0912r5.html}}, 2221 2217 } 2222 2218 … … 2229 2225 month = jun, 2230 2226 year = 2022, 2231 note = {\ href{https://en.cppreference.com/w/cpp/language/coroutines}{https://\-en.cppreference.com/\-w/\-cpp/\-language/\-coroutines}},2227 note = {\url{https://en.cppreference.com/w/cpp/language/coroutines}}, 2232 2228 } 2233 2229 … … 2283 2279 title = {CS343}, 2284 2280 year = 2018, 2285 howpublished= {\ href{https://www.student.cs.uwaterloo.ca/~cs343}{https://\-www.student.cs.uwaterloo.ca/\-$\sim$cs343}},2281 howpublished= {\url{https://www.student.cs.uwaterloo.ca/~cs343}}, 2286 2282 } 2287 2283 … … 2309 2305 address = {Vienna Virginia, U.S.A.}, 2310 2306 year = 2016, 2311 note = {\ href{http://dlang.org/spec/spec.html}{http://\-dlang.org/\-spec/\-spec.html}},2307 note = {\url{http://dlang.org/spec/spec.html}}, 2312 2308 } 2313 2309 … … 2786 2782 author = {Martin Odersky}, 2787 2783 title = {Dotty}, 2788 howpublished= {\ href{https://github.com/lampepfl/dotty}{https://\-github.com/\-lampepfl/\-dotty}},2784 howpublished= {\url{https://github.com/lampepfl/dotty}}, 2789 2785 note = {Acessed: 2019-02-22} 2790 2786 } … … 2797 2793 month = nov, 2798 2794 year = 1983, 2799 note = {\ href{http://www.lysator.liu.se/c/duffs-device.html}{http://\-www.lysator.liu.se/\-c/\-duffs-device.html}}2795 note = {\url{http://www.lysator.liu.se/c/duffs-device.html}} 2800 2796 } 2801 2797 … … 3033 3029 month = aug, 3034 3030 note = {WikipediA}, 3035 howpublished= {\href{http://www.akkadia.org/drepper/tls.pdf} 3036 {http://\-www.akkadia.org/\-drepper/\-tls.pdf}}, 3031 howpublished= {\url{http://www.akkadia.org/drepper/tls.pdf}}, 3037 3032 } 3038 3033 … … 3045 3040 month = may, 3046 3041 note = {Electronic Engineering Times}, 3047 howpublished= {\href{https://www.eetimes.com/author.asp?sectionid=36&doc_id=1287712} 3048 {https://\-www.eetimes.com/\-author.asp?sectionid=\-36&doc_id=1287712}}, 3042 howpublished= {\url{https://www.eetimes.com/author.asp?sectionid=36&doc_id=1287712}}, 3049 3043 } 3050 3044 … … 3159 3153 month = sep, 3160 3154 year = 2016, 3161 note = {\ href{http://erlang.org/doc/pdf/otp-system-documentation.pdf}{http://\-erlang.org/\-doc/\-pdf/\-otp-system-documentation.pdf}},3155 note = {\url{http://erlang.org/doc/pdf/otp-system-documentation.pdf}}, 3162 3156 } 3163 3157 … … 3482 3476 title = {Extensions to the {C} Language Family}, 3483 3477 year = 2014, 3484 howpublished= {\ href{https://gcc.gnu.org/onlinedocs/gcc-4.7.2/gcc/C-Extensions.html}{https://\-gcc.gnu.org/\-onlinedocs/\-gcc-4.7.2/\-gcc/\-C\-Extensions.html}},3478 howpublished= {\url{https://gcc.gnu.org/onlinedocs/gcc-4.7.2/gcc/C-Extensions.html}}, 3485 3479 } 3486 3480 … … 3565 3559 month = feb, 3566 3560 publisher = {John Wiley \& Sons}, 3567 note = {\ href{https://doi.org/10.1002/cpe.4183}{https://\-doi.org/\-10.1002/\-cpe.4183}}3561 note = {\url{https://doi.org/10.1002/cpe.4183}} 3568 3562 } 3569 3563 … … 3587 3581 title = {Fibers}, 3588 3582 organization= {Microsoft, Windows Development Center}, 3589 address = {\ href{https://docs.microsoft.com/en-us/windows/desktop/ProcThread/fibers}{https://\-docs.microsoft.com/\-en-us/\-windows/\-desktop/\-ProcThread/\-fibers}},3583 address = {\url{https://docs.microsoft.com/en-us/windows/desktop/ProcThread/fibers}}, 3590 3584 year = 2018, 3591 3585 } … … 3609 3603 month = jan, 3610 3604 address = {Waterloo, Ontario, Canada, N2L 3G1}, 3611 note = {\ href{http://uwspace.uwaterloo.ca/bitstream/10012/3501/1/Thesis.pdf}{http://\-uwspace.uwaterloo.ca/\-bitstream/\-10012/\-3501/\-1/\-Thesis.pdf}},3605 note = {\url{http://uwspace.uwaterloo.ca/bitstream/10012/3501/1/Thesis.pdf}}, 3612 3606 } 3613 3607 … … 3644 3638 title = {Facebook Open-source Library}, 3645 3639 organization= {Facebook}, 3646 address = {\ href{https://github.com/facebook/folly}{https://\-github.com/\-facebook/\-folly}},3640 address = {\url{https://github.com/facebook/folly}}, 3647 3641 year = 2018, 3648 3642 } … … 3685 3679 address = {Geneva, Switzerland}, 3686 3680 year = 2010, 3687 note = {\ href{https://www.iso.org/standard/50459.html}{https://\-www.iso.org/\-standard/\-50459.html}},3681 note = {\url{https://www.iso.org/standard/50459.html}}, 3688 3682 } 3689 3683 … … 3697 3691 address = {Geneva, Switzerland}, 3698 3692 year = 2018, 3699 note = {\ href{https://www.iso.org/standard/72320.html}{https://\-www.iso.org/\-standard/\-72320.html}},3693 note = {\url{https://www.iso.org/standard/72320.html}}, 3700 3694 } 3701 3695 … … 3928 3922 address = {GNU}, 3929 3923 year = 2016, 3930 note = {\ href{https://gmplib.org}{https://\-gmplib.org}},3924 note = {\url{https://gmplib.org}}, 3931 3925 } 3932 3926 … … 3939 3933 organization= {Google}, 3940 3934 year = 2009, 3941 note = {\ href{http://golang.org/ref/spec}{http://\-golang.org/\-ref/\-spec}},3935 note = {\url{http://golang.org/ref/spec}}, 3942 3936 } 3943 3937 … … 4043 4037 edition = {{S}imon {M}arlow}, 4044 4038 year = 2010, 4045 note = {\ href{https://haskell.org/definition/haskell2010.pdf}{https://\-haskell.org/\-definition/\-haskell2010.pdf}},4039 note = {\url{https://haskell.org/definition/haskell2010.pdf}}, 4046 4040 } 4047 4041 … … 4118 4112 number = 12, 4119 4113 pages = {2463-2500}, 4120 note = {\url{https://onlinelibrary.wiley.com/doi/10.1002/spe.3262} ,4114 note = {\url{https://onlinelibrary.wiley.com/doi/10.1002/spe.3262}}, 4121 4115 } 4122 4116 … … 4127 4121 year = 2019, 4128 4122 optaddress = {Waterloo, Ontario, Canada, N2L 3G1}, 4129 note = {\ href{https://uwspace.uwaterloo.ca/handle/10012/14706}{https://\-uwspace.uwaterloo.ca/\-handle/\-10012/\-14706}},4123 note = {\url{https://uwspace.uwaterloo.ca/handle/10012/14706}}, 4130 4124 } 4131 4125 … … 4186 4180 month = sep, 4187 4181 publisher = {John Wiley \& Sons}, 4188 note = {\ href{https://doi.org/10.1002/cpe.4475}{https://\-doi.org/\-10.1002/\-cpe.4475}},4182 note = {\url{https://doi.org/10.1002/cpe.4475}}, 4189 4183 } 4190 4184 … … 4320 4314 year = 2003, 4321 4315 optaddress = {Waterloo, Ontario, Canada, N2L 3G1}, 4322 note = {\ href{http://plg.uwaterloo.ca/theses/BilsonThesis.pdf}{http://\-plg.uwaterloo.ca/\-theses/\-BilsonThesis.pdf}},4316 note = {\url{http://plg.uwaterloo.ca/theses/BilsonThesis.pdf}}, 4323 4317 } 4324 4318 … … 4733 4727 title = {JDK 1.1 for Solaris Developer's Guide}, 4734 4728 publisher = {Oracle}, 4735 address = {\ href{https://docs.oracle.com/cd/E19455-01/806-3461/6jck06gqk/index.html#ch2mt-41}{https://\-docs.oracle.com/\-cd/\-E19455-01/\-806-3461/\-6jck06gqk/\-index.html\#ch2mt-41}},4729 address = {\url{https://docs.oracle.com/cd/E19455-01/806-3461/6jck06gqk/index.html#ch2mt-41}}, 4736 4730 year = 2010, 4737 4731 } … … 4744 4738 organization= {Oracle}, 4745 4739 year = 2014, 4746 note = {\ href{http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/package-summary.html}{http://docs.oracle.com/\-javase/7/\-docs/\-api/\-java/\-util/\-concurrent/\-package-summary.html}},4740 note = {\url{http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/package-summary.html}}, 4747 4741 } 4748 4742 … … 4873 4867 title = {Labels as Values}, 4874 4868 year = {since gcc-3}, 4875 howpublished= {\href{https://gcc.gnu.org/onlinedocs/gcc/Labels-as-Values.html} 4876 {https:\-//gcc.gnu.org/\-onlinedocs/\-gcc/\-Labels-as-Values.html}}, 4869 howpublished= {\url{https://gcc.gnu.org/onlinedocs/gcc/Labels-as-Values.html}}, 4877 4870 } 4878 4871 … … 4931 4924 title = {libdill Thread Library}, 4932 4925 year = 2019, 4933 howpublished= {\href{http://libdill.org/libdill-2.14.tar.gz} 4934 {http://\-libdill.org/\-libdill-2.14.tar.gz}}, 4926 howpublished= {\url{http://libdill.org/libdill-2.14.tar.gz}}, 4935 4927 } 4936 4928 … … 4939 4931 author = {Martin Karsten}, 4940 4932 title = {{libfibre:~User-Level Threading Runtime}}, 4941 howpublished= {\ href{https://git.uwaterloo.ca/mkarsten/libfibre}{https://\-git.uwaterloo.ca/\-mkarsten/\-libfibre}},4933 howpublished= {\url{https://git.uwaterloo.ca/mkarsten/libfibre}}, 4942 4934 note = {[Online; accessed 2020-04-15]}, 4943 4935 } … … 4962 4954 title = {{G}o-style concurrency in {C}, Version 1.18}, 4963 4955 organization= {libmill}, 4964 address = {\ href{http://libmill.org/documentation.html}{http://\-libmill.org/\-documentation.html}},4956 address = {\url{http://libmill.org/documentation.html}}, 4965 4957 month = jan, 4966 4958 year = 2017, … … 5038 5030 month = jan, 5039 5031 year = 2017, 5040 howpublished= {\href{http://smallcultfollowing.com/babysteps/blog/2017/01/26/lowering-rust-traits-to-logic/} 5041 {http://smallcultfollowing.com/\-babysteps/\-blog/\-2017/\-01/\-26/\-lowering-rust-traits-to-logic/}}, 5032 howpublished= {\url{http://smallcultfollowing.com/babysteps/blog/2017/01/26/lowering-rust-traits-to-logic/}}, 5042 5033 optnote = {Accessed: 2019-01}, 5043 5034 } … … 5063 5054 title = {Lua 5.4 Reference Manual}, 5064 5055 organization= {Pontifical Catholic University}, 5065 address = {\ href{https://www.lua.org/manual/5.4}{https://\-www.lua.org/\-manual/\-5.4}},5056 address = {\url{https://www.lua.org/manual/5.4}}, 5066 5057 year = 2020, 5067 5058 } … … 5084 5075 title = {Making arbitrarily-large binaries from fixed-size {C}{\kern-.1em\hbox{\large\texttt{+\kern-.25em+}}} code}, 5085 5076 year = 2016, 5086 howpublished= {\href{http://blog.reverberate.org/2016/01/making-arbitrarily-large-binaries-from.html} 5087 {http://blog.reverberate.org/\-2016/\-01/\-making-arbitrarily-large-binaries-from.html}}, 5077 howpublished= {\url{http://blog.reverberate.org/2016/01/making-arbitrarily-large-binaries-from.html}}, 5088 5078 optnote = {Accessed: 2016-09}, 5089 5079 } … … 5118 5108 title = {Marcel Thread Library}, 5119 5109 year = 2011, 5120 howpublished= {\href{https://gforge.inria.fr/frs/download.php/file/28643/marcel-2.99.3.tar.gz} 5121 {https://\-gforge.inria.fr/\-frs/\-download.php/\-file/\-28643/\-marcel-2.99.3.tar.gz}}, 5110 howpublished= {\url{https://gforge.inria.fr/frs/download.php/file/28643/marcel-2.99.3.tar.gz}}, 5122 5111 } 5123 5112 … … 5264 5253 month = sep, 5265 5254 year = 1994, 5266 note = {\ href{https://plg.uwaterloo.ca/~usystem/pub/uSystem/uSystem.pdf}{https://\-plg.uwaterloo.ca/\-$\sim$usystem/\-pub/\-uSystem/\-uSystem.pdf}},5255 note = {\url{https://plg.uwaterloo.ca/~usystem/pub/uSystem/uSystem.pdf}}, 5267 5256 } 5268 5257 … … 5463 5452 month = jun, 5464 5453 year = 2015, 5465 note = {\ href{http://www.mpi-forum.org/docs/mpi-3.1/mpi31-report.pdf}{http://www.mpi-forum.org/\-docs/\-mpi-3.1/\-mpi31-report.pdf}},5454 note = {\url{http://www.mpi-forum.org/docs/mpi-3.1/mpi31-report.pdf}}, 5466 5455 } 5467 5456 … … 5613 5602 year = 1980, 5614 5603 pages = {833-842}, 5615 note = {\ href{http://groups.csail.mit.edu/tds/papers/Lynch/allertonconf.pdf}{http://\-groups.csail.mit.edu/\-tds/\-papers/\-Lynch/\-allertonconf.pdf} [Accessed on March 2014]},5604 note = {\url{http://groups.csail.mit.edu/tds/papers/Lynch/allertonconf.pdf}}, 5616 5605 optnote = {\textsf{http://\-groups.csail.mit.edu/\-tds/\-papers/\-Lynch/\-allertonconf.pdf}}, 5617 5606 } … … 5639 5628 institution = {Red Hat}, 5640 5629 year = 2003, 5641 note = {\ href{http://www.cs.utexas.edu/~witchel/372/lectures/POSIX_Linux_Threading.pdf}{http://www.cs.utexas.edu/\-$\sim$witchel/\-372/\-lectures/\-POSIX\_Linux\_Threading.pdf}},5630 note = {\url{http://www.cs.utexas.edu/~witchel/372/lectures/POSIX_Linux_Threading.pdf}}, 5642 5631 } 5643 5632 … … 5649 5638 organization= {{gcc} 9.3 Manual}, 5650 5639 year = 2019, 5651 note = {\ href{https://gcc.gnu.org/onlinedocs/gcc-9.3.0/gcc/Nested-Functions.html}{https://\-gcc.gnu.org/\-onlinedocs/\-gcc-9.3.0/\-gcc/\-Nested-Functions.html}},5640 note = {\url{https://gcc.gnu.org/onlinedocs/gcc-9.3.0/gcc/Nested-Functions.html}}, 5652 5641 } 5653 5642 … … 5718 5707 year = 1990, 5719 5708 pages = {41-51}, 5720 note = {\ href{http://doc.cat-v.org/bell_labs/new_c_compilers/new_c_compiler.pdf}{http://\-doc.cat-v.org/\-bell\_labs/\-new\_c\_compilers/\-new\_c\_compiler.pdf}},5709 note = {\url{http://doc.cat-v.org/bell_labs/new_c_compilers/new_c_compiler.pdf}}, 5721 5710 } 5722 5711 … … 5781 5770 key = {nginx}, 5782 5771 author = {{NGINX}}, 5783 howpublished= {\ href{https://www.nginx.com}{https://\-www.nginx.com}},5772 howpublished= {\url{https://www.nginx.com}}, 5784 5773 } 5785 5774 … … 5910 5899 publisher = {Apple Inc.}, 5911 5900 year = 2014, 5912 howpublished= {\ href{https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/ProgrammingWithObjectiveC}{https://\-developer.apple.com/\-library/archive/\-documentation/\-Cocoa/\-Conceptual/\-ProgrammingWithObjectiveC}},5901 howpublished= {\url{https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/ProgrammingWithObjectiveC}}, 5913 5902 } 5914 5903 … … 5919 5908 title = {{X}code 7 Release Notes}, 5920 5909 year = 2015, 5921 howpublished= {\ href{https://developer.apple.com/library/content/documentation/Xcode/Conceptual/RN-Xcode-Archive/Chapters/xc7_release_notes.html}{https://\-developer.apple.com/\-library/\-content/\-documentation/\-Xcode/\-Conceptual/\-RN-Xcode-Archive/\-Chapters/\-xc7\_release\_notes.html}},5910 howpublished= {\url{https://developer.apple.com/library/content/documentation/Xcode/Conceptual/RN-Xcode-Archive/Chapters/xc7_release_notes.html}}, 5922 5911 } 5923 5912 … … 6052 6041 month = nov, 6053 6042 year = 2015, 6054 note = {\ href{https://www.openmp.org/wp-content/uploads/openmp-4.5.pdf}{https://\-www.openmp.org/\-wp-content/\-uploads/\-openmp-4.5.pdf}},6043 note = {\url{https://www.openmp.org/wp-content/uploads/openmp-4.5.pdf}}, 6055 6044 } 6056 6045 … … 6060 6049 title = {OpenTelemetry}, 6061 6050 author = {{Asynkron AB}}, 6062 howpublished= {\ href{https://proto.actor/docs/tracing}{https://\-proto.actor/\-docs/\-tracing}},6051 howpublished= {\url{https://proto.actor/docs/tracing}}, 6063 6052 year = 2022, 6064 6053 } … … 6461 6450 key = {perf}, 6462 6451 author = {perf}, 6463 howpublished= {\ href{https://perf.wiki.kernel.org/index.php/Tutorial}{https://\-perf.wiki.kernel.org/\-index.php/\-Tutorial}},6452 howpublished= {\url{https://perf.wiki.kernel.org/index.php/Tutorial}}, 6464 6453 } 6465 6454 … … 6470 6459 month = may, 6471 6460 year = 2012, 6472 howpublished= {\ href{http://cs.brown.edu/research/pubs/theses/masters/2012/verch.pdf}{http://cs.brown.edu/\-research/\-pubs/\-theses/\-masters/\-2012/\-verch.pdf}},6461 howpublished= {\url{http://cs.brown.edu/research/pubs/theses/masters/2012/verch.pdf}}, 6473 6462 } 6474 6463 … … 6869 6858 address = {Geneva, Switzerland}, 6870 6859 year = 1998, 6871 note = {\ href{https://www.iso.org/standard/25845.html}{https://\-www.iso.org/\-standard/\-25845.html}},6860 note = {\url{https://www.iso.org/standard/25845.html}}, 6872 6861 } 6873 6862 … … 6881 6870 address = {Geneva, Switzerland}, 6882 6871 year = 2014, 6883 note = {\ href{https://www.iso.org/standard/64029.html}{https://\-www.iso.org/\-standard/\-64029.html}},6872 note = {\url{https://www.iso.org/standard/64029.html}}, 6884 6873 } 6885 6874 … … 6893 6882 address = {Geneva, Switzerland}, 6894 6883 year = 2017, 6895 note = {\ href{https://www.iso.org/standard/68564.html}{https://\-www.iso.org/\-standard/\-68564.html}},6884 note = {\url{https://www.iso.org/standard/68564.html}}, 6896 6885 } 6897 6886 … … 7173 7162 author = {IEEE and {The Open Group}}, 7174 7163 year = 2018, 7175 howpublished= {\href{http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/pthread.h.html} 7176 {http://\-pubs.opengroup.org/\-onlinepubs/\-9699919799/\-basedefs/\-pthread.h.html}}, 7164 howpublished= {\url{http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/pthread.h.html}}, 7177 7165 } 7178 7166 … … 7183 7171 title = {Python Language Reference, Release 3.7.2}, 7184 7172 organization= {Python Software Foundation}, 7185 address = {\ href{https://docs.python.org/3/reference/index.html}{https://\-docs.python.org/\-3/\-reference/\-index.html}},7173 address = {\url{https://docs.python.org/3/reference/index.html}}, 7186 7174 year = 2018, 7187 7175 } … … 7238 7226 title = {Quasar Documentation, Release 0.8.0}, 7239 7227 organization= {Parallel Universe}, 7240 address = {\ href{http://docs.paralleluniverse.co/quasar}{http://\-docs.paralleluniverse.co/\-quasar}},7228 address = {\url{http://docs.paralleluniverse.co/quasar}}, 7241 7229 year = 2018, 7242 7230 } … … 7378 7366 month = apr, 7379 7367 type = {Diplomarbeit}, 7380 note = {\ href{https://plg.uwaterloo.ca/~usystem/theses/SchusterThesis.pdf}{https://\-plg.uwaterloo.ca/\-$\sim$usystem/\-theses/\-SchusterThesis.pdf}},7368 note = {\url{https://plg.uwaterloo.ca/~usystem/theses/SchusterThesis.pdf}}, 7381 7369 } 7382 7370 … … 7413 7401 year = 2017, 7414 7402 optaddress = {Waterloo, Ontario, Canada, N2L 3G1}, 7415 note = {\ href{https://uwspace.uwaterloo.ca/handle/10012/11830}{https://\-uwspace.uwaterloo.ca/\-handle/\-10012/\-11830}},7403 note = {\url{https://uwspace.uwaterloo.ca/handle/10012/11830}}, 7416 7404 } 7417 7405 … … 7491 7479 month = apr, 7492 7480 year = 2022, 7493 howpublished= {\ href{https://github.com/mjansson/rpmalloc}{https://\-github.com/\-mjansson/\-rpmalloc}},7481 howpublished= {\url{https://github.com/mjansson/rpmalloc}}, 7494 7482 } 7495 7483 … … 7501 7489 optaddress = {Rust Project Developers}, 7502 7490 year = 2015, 7503 note = {\ href{https://doc.rust-lang.org/reference.html}{https://\-doc.rust-lang\-.org/\-reference.html}},7491 note = {\url{https://doc.rust-lang.org/reference.html}}, 7504 7492 } 7505 7493 … … 7510 7498 title = {Ruby Documentation, Release 2.6.0}, 7511 7499 organization= {Python Software Foundation}, 7512 address = {\ href{https://www.ruby-lang.org/en/documentation}{https://\-www.ruby-lang.org/\-en/\-documentation}},7500 address = {\url{https://www.ruby-lang.org/en/documentation}}, 7513 7501 year = 2018, 7514 7502 } … … 7538 7526 address = {\'{E}cole Polytechnique F\'{e}d\'{e}rale de Lausanne}, 7539 7527 year = 2016, 7540 note = {\ href{http://www.scala-lang.org/files/archive/spec/2.11}{http://\-www.scala-lang.org/\-files/\-archive/\-spec/\-2.11}},7528 note = {\url{http://www.scala-lang.org/files/archive/spec/2.11}}, 7541 7529 } 7542 7530 … … 7699 7687 month = sep, 7700 7688 year = 1995, 7701 note = {\ href{http://www.hpl.hp.com/techreports/Compaq-DEC/WRL-95-7.pdf}{http://www.hpl.hp.com/\-techreports/\-Compaq-DEC/\-WRL-95-7.pdf}, Reprinted in \cite{Adve95reprint}.},7689 note = {\url{http://www.hpl.hp.com/techreports/Compaq-DEC/WRL-95-7.pdf}}, 7702 7690 } 7703 7691 … … 7773 7761 month = may, 7774 7762 year = 2001, 7775 note = {\ href{http://www.python.org/peps/pep-0255.html}{http://\-www.python.org/\-peps/\-pep-0255.html}},7763 note = {\url{http://www.python.org/peps/pep-0255.html}}, 7776 7764 } 7777 7765 … … 8076 8064 organization= {IEEE and The Open Group}, 8077 8065 year = 2017, 8078 note = {\ href{https://pubs.opengroup.org/onlinepubs/9699919799}{https://\-pubs.opengroup.org/\-onlinepubs/\-9699919799}},8066 note = {\url{https://pubs.opengroup.org/onlinepubs/9699919799}}, 8079 8067 } 8080 8068 … … 8143 8131 pages = {1-6}, 8144 8132 numpages = {6}, 8145 howpublished= {\ href{http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0144r0.pdf}{http://\-www.open-std.org/\-jtc1/\-sc22/\-wg21/\-docs/\-papers/\-2015/\-p0144r0.pdf}},8133 howpublished= {\url{http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0144r0.pdf}}, 8146 8134 } 8147 8135 … … 8453 8441 key = {TIOBE Index}, 8454 8442 author = {{TIOBE Index}}, 8455 howpublished= {\ href{http://www.tiobe.com/tiobe_index}{http://\-www.tiobe.com/\-tiobe\_index}},8443 howpublished= {\url{http://www.tiobe.com/tiobe_index}}, 8456 8444 } 8457 8445 … … 8461 8449 title = {Thread (computing)}, 8462 8450 author = {{Threading Model}}, 8463 howpublished= {\ href{https://en.wikipedia.org/wiki/Thread_(computing)}{https://\-en.wikipedia.org/\-wiki/\-Thread\_\-(computing)}},8451 howpublished= {\url{https://en.wikipedia.org/wiki/Thread_(computing)}}, 8464 8452 } 8465 8453 … … 8469 8457 title = {{T}okio Asynchronous Runtime for {R}ust}, 8470 8458 author = {Tokio}, 8471 howpublished= {\ href{https://tokio.rs}{https://\-tokio.rs}},8459 howpublished= {\url{https://tokio.rs}}, 8472 8460 } 8473 8461 … … 8609 8597 key = {Trace Compass}, 8610 8598 author = {{T}race {C}ompass}, 8611 howpublished= {\ href{https://projects.eclipse.org/proposals/trace-compass}{https://\-projects.eclipse.org/\-proposals/\-trace-compass}},8599 howpublished= {\url{https://projects.eclipse.org/proposals/trace-compass}}, 8612 8600 } 8613 8601 … … 8668 8656 title = {Typed Actors}, 8669 8657 author = {{Lightbend}}, 8670 howpublished= {\ href{https://doc.akka.io/docs/akka/2.5/typed-actors.html}{https://\-doc.akka.io/\-docs/\-akka/\-2.5/\-typed-actors.html}},8658 howpublished= {\url{https://doc.akka.io/docs/akka/2.5/typed-actors.html}}, 8671 8659 year = 2022, 8672 8660 } … … 8938 8926 year = 2020, 8939 8927 note = {WikipediA}, 8940 howpublished= {\href{https://en.wikipedia.org/wiki/Visitor\_pattern} 8941 {https://\-en.wikipedia.org/\-wiki/\-Visitor\_pattern}}, 8928 howpublished= {\url{https://en.wikipedia.org/wiki/Visitor\_pattern}}, 8942 8929 } 8943 8930 … … 9041 9028 month = jun, 9042 9029 year = 1985, 9043 note = {\ href{http://www.hpl.hp.com/techreports/tandem/TR-85.7.pdf}{http://www.hpl.hp.com/\-techreports/\-tandem/\-TR-85.7.pdf}},9030 note = {\url{http://www.hpl.hp.com/techreports/tandem/TR-85.7.pdf}}, 9044 9031 } 9045 9032 -
doc/papers/llheap/Paper.tex
rc75b30a r32490deb 77 77 \lstset{ 78 78 columns=fullflexible, 79 basicstyle=\linespread{0.9}\sf, % reduce line spacing and use sanserif font 80 stringstyle=\tt, % use typewriter font 81 tabsize=5, % N space tabbing 82 xleftmargin=\parindentlnth, % indent code to paragraph indentation 83 %mathescape=true, % LaTeX math escape in CFA code $...$ 84 escapechar=\$, % LaTeX escape in CFA code 85 keepspaces=true, % 86 showstringspaces=false, % do not show spaces with cup 87 showlines=true, % show blank lines at end of code 88 aboveskip=4pt, % spacing above/below code block 89 belowskip=3pt, 90 moredelim=**[is][\color{red}]{`}{`}, 79 basicstyle=\linespread{0.9}\sf, % reduce line spacing and use sanserif font 80 stringstyle=\small\tt, % use typewriter font 81 tabsize=5, % N space tabbing 82 xleftmargin=\parindentlnth, % indent code to paragraph indentation 83 escapechar=\$, % LaTeX escape in CFA code 84 %mathescape=true, % LaTeX math escape in CFA code $...$ 85 keepspaces=true, % 86 showstringspaces=false, % do not show spaces with cup 87 showlines=true, % show blank lines at end of code 88 aboveskip=4pt, % spacing above/below code block 89 belowskip=2pt, 90 numberstyle=\footnotesize\sf, % numbering style 91 moredelim=**[is][\color{red}]{@}{@}, 91 92 }% lstset 92 93 … … 1082 1083 1083 1084 The primary design objective for llheap is low-latency across all allocator calls independent of application access-patterns and/or number of threads, \ie very seldom does the allocator have a delay during an allocator call. 1084 (Large allocations requiring initialization, \eg zero fill, and/or copying are not covered by the low-latency objective.) 1085 Excluded from the low-latency objective are (large) allocations requiring initialization, \eg zero fill, and/or data copying, which are outside the allocator's purview. 1085 1086 A direct consequence of this objective is very simple or no storage coalescing; 1086 1087 hence, llheap's design is willing to use more storage to lower latency. 1087 1088 This objective is apropos because systems research and industrial applications are striving for low latency and computers have huge amounts of RAM memory. 1088 Finally, llheap's performance should be comparable with the current best allocators (see performance comparison in Section~\ref{c:Performance}).1089 Finally, llheap's performance should be comparable with the current best allocators, both in space and time (see performance comparison in Section~\ref{c:Performance}). 1089 1090 1090 1091 % The objective of llheap's new design was to fulfill following requirements: … … 1205 1206 % \label{s:AllocationFastpath} 1206 1207 1207 llheap's design was reviewed and changed multiple times during its development. Only the final design choices are 1208 discussed in this paper. 1208 llheap's design was reviewed and changed multiple times during its development, with the final choices are discussed here. 1209 1209 (See~\cite{Zulfiqar22} for a discussion of alternate choices and reasons for rejecting them.) 1210 1210 All designs were analyzed for the allocation/free \newterm{fastpath}, \ie when an allocation can immediately return free storage or returned storage is not coalesced. 1211 The heap model cho osen is 1:1, which is the T:H model with T = H, where there is one thread-local heap for each KT.1211 The heap model chosen is 1:1, which is the T:H model with T = H, where there is one thread-local heap for each KT. 1212 1212 (See Figure~\ref{f:THSharedHeaps} but with a heap bucket per KT and no bucket or local-pool lock.) 1213 1213 Hence, immediately after a KT starts, its heap is created and just before a KT terminates, its heap is (logically) deleted. … … 1426 1426 1427 1427 1428 Algorithm~\ref{alg:heapObjectFreeOwn} shows the de -allocation (free) outline for an object at address $A$ with ownership.1428 Algorithm~\ref{alg:heapObjectFreeOwn} shows the deallocation (free) outline for an object at address $A$ with ownership. 1429 1429 First, the address is divided into small (@sbrk@) or large (@mmap@). 1430 1430 For large allocations, the storage is unmapped back to the OS. … … 1433 1433 If the bucket is not local to the thread, the allocation is pushed onto the owning thread's associated away stack. 1434 1434 1435 Algorithm~\ref{alg:heapObjectFreeNoOwn} shows the de -allocation (free) outline for an object at address $A$ without ownership.1435 Algorithm~\ref{alg:heapObjectFreeNoOwn} shows the deallocation (free) outline for an object at address $A$ without ownership. 1436 1436 The algorithm is the same as for ownership except if the bucket is not local to the thread. 1437 1437 Then the corresponding bucket of the owner thread is computed for the deallocating thread, and the allocation is pushed onto the deallocating thread's bucket. … … 1792 1792 The C dynamic-memory API is extended with the following routines: 1793 1793 1794 \paragraph{\lstinline{void * aalloc( size_t dim, size_t elemSize )}} 1795 extends @calloc@ for allocating a dynamic array of objects without calculating the total size of array explicitly but \emph{without} zero-filling the memory. 1796 @aalloc@ is significantly faster than @calloc@, which is the only alternative given by the standard memory-allocation routines. 1797 1798 \noindent\textbf{Usage} 1799 @aalloc@ takes two parameters. 1800 \begin{itemize}[topsep=3pt,itemsep=2pt,parsep=0pt] 1801 \item 1802 @dim@: number of array objects 1803 \item 1804 @elemSize@: size of array object 1805 \end{itemize} 1794 \medskip\noindent 1795 \lstinline{void * aalloc( size_t dim, size_t elemSize )} 1796 extends @calloc@ for allocating a dynamic array of objects with total size @dim@ $\times$ @elemSize@ but \emph{without} zero-filling the memory. 1797 @aalloc@ is significantly faster than @calloc@, which is the only alternative given by the standard memory-allocation routines for array allocation. 1806 1798 It returns the address of the dynamic array or @NULL@ if either @dim@ or @elemSize@ are zero. 1807 1799 1808 \paragraph{\lstinline{void * resize( void * oaddr, size_t size )}} 1809 extends @realloc@ for resizing an existing allocation \emph{without} copying previous data into the new allocation or preserving sticky properties. 1800 \medskip\noindent 1801 \lstinline{void * resize( void * oaddr, size_t size )} 1802 extends @realloc@ for resizing an existing allocation, @oaddr@, to the new @size@ (smaller or larger than previous) \emph{without} copying previous data into the new allocation or preserving sticky properties. 1810 1803 @resize@ is significantly faster than @realloc@, which is the only alternative. 1811 1812 \noindent\textbf{Usage}1813 @resize@ takes two parameters.1814 \begin{itemize}[topsep=3pt,itemsep=2pt,parsep=0pt]1815 \item1816 @oaddr@: address to be resized1817 \item1818 @size@: new allocation size (smaller or larger than previous)1819 \end{itemize}1820 1804 It returns the address of the old or new storage with the specified new size or @NULL@ if @size@ is zero. 1821 1805 1822 \paragraph{\lstinline{void * amemalign( size_t alignment, size_t dim, size_t elemSize )}} 1823 extends @aalloc@ and @memalign@ for allocating an aligned dynamic array of objects. 1806 \medskip\noindent 1807 \lstinline{void * amemalign( size_t alignment, size_t dim, size_t elemSize )} 1808 extends @aalloc@ and @memalign@ for allocating a dynamic array of objects with the starting address on the @alignment@ boundary. 1824 1809 Sets sticky alignment property. 1825 1826 \noindent\textbf{Usage}1827 @amemalign@ takes three parameters.1828 \begin{itemize}[topsep=3pt,itemsep=2pt,parsep=0pt]1829 \item1830 @alignment@: alignment requirement1831 \item1832 @dim@: number of array objects1833 \item1834 @elemSize@: size of array object1835 \end{itemize}1836 1810 It returns the address of the aligned dynamic-array or @NULL@ if either @dim@ or @elemSize@ are zero. 1837 1811 1838 \paragraph{\lstinline{void * cmemalign( size_t alignment, size_t dim, size_t elemSize )}} 1812 \medskip\noindent 1813 \lstinline{void * cmemalign( size_t alignment, size_t dim, size_t elemSize )} 1839 1814 extends @amemalign@ with zero fill and has the same usage as @amemalign@. 1840 1815 Sets sticky zero-fill and alignment property. 1841 1816 It returns the address of the aligned, zero-filled dynamic-array or @NULL@ if either @dim@ or @elemSize@ are zero. 1842 1817 1843 \paragraph{\lstinline{size_t malloc_alignment( void * addr )}} 1844 returns the alignment of the dynamic object for use in aligning similar allocations. 1845 1846 \noindent\textbf{Usage} 1847 @malloc_alignment@ takes one parameter. 1848 \begin{itemize}[topsep=3pt,itemsep=2pt,parsep=0pt] 1849 \item 1850 @addr@: address of an allocated object. 1851 \end{itemize} 1852 It returns the alignment of the given object, where objects not allocated with alignment return the minimal allocation alignment. 1853 1854 \paragraph{\lstinline{bool malloc_zero_fill( void * addr )}} 1855 returns true if the object has the zero-fill sticky property for use in zero filling similar allocations. 1856 1857 \noindent\textbf{Usage} 1858 @malloc_zero_fill@ takes one parameters. 1859 1860 \begin{itemize}[topsep=3pt,itemsep=2pt,parsep=0pt] 1861 \item 1862 @addr@: address of an allocated object. 1863 \end{itemize} 1864 It returns true if the zero-fill sticky property is set and false otherwise. 1865 1866 \paragraph{\lstinline{size_t malloc_size( void * addr )}} 1867 returns the request size of the dynamic object (updated when an object is resized) for use in similar allocations. 1868 See also @malloc_usable_size@. 1869 1870 \noindent\textbf{Usage} 1871 @malloc_size@ takes one parameters. 1872 \begin{itemize}[topsep=3pt,itemsep=2pt,parsep=0pt] 1873 \item 1874 @addr@: address of an allocated object. 1875 \end{itemize} 1876 It returns the request size or zero if @addr@ is @NULL@. 1877 1878 \paragraph{\lstinline{int malloc_stats_fd( int fd )}} 1879 changes the file descriptor where @malloc_stats@ writes statistics (default @stdout@). 1880 1881 \noindent\textbf{Usage} 1882 @malloc_stats_fd@ takes one parameters. 1883 \begin{itemize}[topsep=3pt,itemsep=2pt,parsep=0pt] 1884 \item 1885 @fd@: file descriptor. 1886 \end{itemize} 1887 It returns the previous file descriptor. 1888 1889 \paragraph{\lstinline{size_t malloc_expansion()}} 1818 \medskip\noindent 1819 \lstinline{size_t malloc_alignment( void * addr )} 1820 returns the object alignment, where objects not allocated with alignment return the minimal allocation alignment. 1821 For use in aligning similar allocations. 1822 1823 \medskip\noindent 1824 \lstinline{bool malloc_zero_fill( void * addr )} 1825 returns true if the objects zero-fill sticky property is set and false otherwise. 1826 For use in zero filling similar allocations. 1827 1828 \medskip\noindent 1829 \lstinline{size_t malloc_size( void * addr )} 1830 returns the object's request size, which is updated when an object is resized or zero if @addr@ is @NULL@ (see also @malloc_usable_size@). 1831 For use in similar allocations. 1832 1833 \medskip\noindent 1834 \lstinline{int malloc_stats_fd( int fd )} 1835 changes the file descriptor where @malloc_stats@ writes statistics (default @stdout@) and returns the previous file descriptor. 1836 1837 \medskip\noindent 1838 \lstinline{size_t malloc_expansion()} 1890 1839 \label{p:malloc_expansion} 1891 1840 set the amount (bytes) to extend the heap when there is insufficient free storage to service an allocation request. 1892 1841 It returns the heap extension size used throughout a program when requesting more memory from the system using @sbrk@ system-call, \ie called once at heap initialization. 1893 1842 1894 \paragraph{\lstinline{size_t malloc_mmap_start()}} 1843 \medskip\noindent 1844 \lstinline{size_t malloc_mmap_start()} 1895 1845 set the crossover between allocations occurring in the @sbrk@ area or separately mapped. 1896 1846 It returns the crossover point used throughout a program, \ie called once at heap initialization. 1897 1847 1898 \paragraph{\lstinline{size_t malloc_unfreed()}} 1848 \medskip\noindent 1849 \lstinline{size_t malloc_unfreed()} 1899 1850 \label{p:malloc_unfreed} 1900 1851 amount subtracted to adjust for unfreed program storage (debug only). 1901 It returns the new subtraction amount and called by @malloc_stats@ .1852 It returns the new subtraction amount and called by @malloc_stats@ (discussed in Section~\ref{}). 1902 1853 1903 1854 … … 1906 1857 The following extensions take advantage of overload polymorphism in the \CC type-system. 1907 1858 1908 \paragraph{\lstinline{void * resize( void * oaddr, size_t nalign, size_t size )}} 1909 extends @resize@ with an alignment re\-quirement. 1910 1911 \noindent\textbf{Usage} 1912 takes three parameters. 1913 \begin{itemize}[topsep=3pt,itemsep=2pt,parsep=0pt] 1914 \item 1915 @oaddr@: address to be resized 1916 \item 1917 @nalign@: alignment requirement 1918 \item 1919 @size@: new allocation size (smaller or larger than previous) 1920 \end{itemize} 1859 \medskip\noindent 1860 \lstinline{void * resize( void * oaddr, size_t nalign, size_t size )} 1861 extends @resize@ with an alignment requirement, @nalign@. 1921 1862 It returns the address of the old or new storage with the specified new size and alignment, or @NULL@ if @size@ is zero. 1922 1863 1923 \paragraph{\lstinline{void * realloc( void * oaddr, size_t nalign, size_t size )}} 1924 extends @realloc@ with an alignment re\-quirement and has the same usage as aligned @resize@. 1864 \medskip\noindent 1865 \lstinline{void * realloc( void * oaddr, size_t nalign, size_t size )} 1866 extends @realloc@ with an alignment requirement, @nalign@. 1867 It returns the address of the old or new storage with the specified new size and alignment, or @NULL@ if @size@ is zero. 1925 1868 1926 1869 … … 1979 1922 object size: like the \CFA's C-interface, programmers do not have to specify object size or cast allocation results. 1980 1923 \end{itemize} 1981 Note, postfix function call is an alternative call syntax, using backtick @`@, wherethe argument appears before the function name, \eg1924 Note, postfix function call is an alternative call syntax, using backtick @`@, so the argument appears before the function name, \eg 1982 1925 \begin{cfa} 1983 1926 duration ?@`@h( int h ); // ? denote the position of the function operand … … 1987 1930 \end{cfa} 1988 1931 1989 \paragraph{\lstinline{T * alloc( ... )} or \lstinline{T * alloc( size_t dim, ... )}} 1932 The following extensions take advantage of overload polymorphism in the \CC type-system. 1933 1934 \medskip\noindent 1935 \lstinline{T * alloc( ... )} or \lstinline{T * alloc( size_t dim, ... )} 1990 1936 is overloaded with a variable number of specific allocation operations, or an integer dimension parameter followed by a variable number of specific allocation operations. 1991 1937 These allocation operations can be passed as named arguments when calling the \lstinline{alloc} routine. … … 1996 1942 1997 1943 The allocation property functions are: 1998 \subparagraph{\lstinline{T_align ?`align( size_t alignment )}} 1944 1945 \medskip\noindent 1946 \lstinline{T_align ?`align( size_t alignment )} 1999 1947 to align the allocation. 2000 The alignment parameter must be $\ge$ the default alignment (@libAlign()@ in \CFA) and a power of two, \eg: 1948 The alignment parameter must be $\ge$ the default alignment (@libAlign()@ in \CFA) and a power of two. 1949 The following example returns a dynamic object and object array aligned on a 4096-byte boundary. 2001 1950 \begin{cfa} 2002 1951 int * i0 = alloc( @4096`align@ ); sout | i0 | nl; … … 2006 1955 0x555555574000 0x555555574000 0x555555574004 0x555555574008 2007 1956 \end{cfa} 2008 returns a dynamic object and object array aligned on a 4096-byte boundary. 2009 2010 \ subparagraph{\lstinline{S_fill(T) ?`fill ( /* various types */ )}}1957 1958 \medskip\noindent 1959 \lstinline{S_fill(T) ?`fill ( /* various types */ )} 2011 1960 to initialize storage. 2012 1961 There are three ways to fill storage: 2013 \begin{enumerate} 1962 \begin{enumerate}[itemsep=0pt,parsep=0pt] 2014 1963 \item 2015 1964 A char fills each byte of each object. … … 2020 1969 \end{enumerate} 2021 1970 For example: 2022 \begin{cfa}[numbers=left ]1971 \begin{cfa}[numbers=left,xleftmargin=2.5\parindentlnth] 2023 1972 int * i0 = alloc( @0n`fill@ ); sout | *i0 | nl; // disambiguate 0 2024 1973 int * i1 = alloc( @5`fill@ ); sout | *i1 | nl; … … 2029 1978 int * i6 = alloc( 5, @[i3, 3]`fill@ ); for ( i; 5 ) sout | i6[i]; sout | nl; 2030 1979 \end{cfa} 2031 \begin{lstlisting}[numbers=left ]1980 \begin{lstlisting}[numbers=left,xleftmargin=2.5\parindentlnth] 2032 1981 0 2033 1982 5 … … 2041 1990 Examples 4 to 7 fill an array of objects with values, another array, or part of an array. 2042 1991 2043 \subparagraph{\lstinline{S_resize(T) ?`resize( void * oaddr )}} 1992 \medskip\noindent 1993 \lstinline{S_resize(T) ?`resize( void * oaddr )} 2044 1994 used to resize, realign, and fill, where the old object data is not copied to the new object. 2045 1995 The old object type may be different from the new object type, since the values are not used. 2046 1996 For example: 2047 \begin{cfa}[numbers=left ]1997 \begin{cfa}[numbers=left,xleftmargin=2.5\parindentlnth] 2048 1998 int * i = alloc( @5`fill@ ); sout | i | *i; 2049 1999 i = alloc( @i`resize@, @256`align@, @7`fill@ ); sout | i | *i; 2050 2000 double * d = alloc( @i`resize@, @4096`align@, @13.5`fill@ ); sout | d | *d; 2051 2001 \end{cfa} 2052 \begin{lstlisting}[numbers=left ]2002 \begin{lstlisting}[numbers=left,xleftmargin=2.5\parindentlnth] 2053 2003 0x55555556d5c0 5 2054 2004 0x555555570000 7 … … 2057 2007 Examples 2 to 3 change the alignment, fill, and size for the initial storage of @i@. 2058 2008 2059 \begin{cfa}[numbers=left ]2009 \begin{cfa}[numbers=left,xleftmargin=2.5\parindentlnth] 2060 2010 int * ia = alloc( 5, @5`fill@ ); for ( i; 5 ) sout | ia[i]; sout | nl; 2061 2011 ia = alloc( 10, @ia`resize@, @7`fill@ ); for ( i; 10 ) sout | ia[i]; sout | nl; … … 2063 2013 ia = alloc( 3, @ia`resize@, @4096`align@, @2`fill@ ); sout | ia; for ( i; 3 ) sout | &ia[i] | ia[i]; sout | nl; 2064 2014 \end{cfa} 2065 \begin{lstlisting}[numbers=left ]2015 \begin{lstlisting}[numbers=left,xleftmargin=2.5\parindentlnth] 2066 2016 5 5 5 5 5 2067 2017 7 7 7 7 7 7 7 7 7 7 … … 2071 2021 Examples 2 to 4 change the array size, alignment and fill for the initial storage of @ia@. 2072 2022 2073 \subparagraph{\lstinline{S_realloc(T) ?`realloc( T * a ))}} 2023 \medskip\noindent 2024 \lstinline{S_realloc(T) ?`realloc( T * a ))} 2074 2025 used to resize, realign, and fill, where the old object data is copied to the new object. 2075 2026 The old object type must be the same as the new object type, since the value is used. 2076 2027 Note, for @fill@, only the extra space after copying the data from the old object is filled with the given parameter. 2077 2028 For example: 2078 \begin{cfa}[numbers=left ]2029 \begin{cfa}[numbers=left,xleftmargin=2.5\parindentlnth] 2079 2030 int * i = alloc( @5`fill@ ); sout | i | *i; 2080 2031 i = alloc( @i`realloc@, @256`align@ ); sout | i | *i; 2081 2032 i = alloc( @i`realloc@, @4096`align@, @13`fill@ ); sout | i | *i; 2082 2033 \end{cfa} 2083 \begin{lstlisting}[numbers=left ]2034 \begin{lstlisting}[numbers=left,xleftmargin=2.5\parindentlnth] 2084 2035 0x55555556d5c0 5 2085 2036 0x555555570000 5 … … 2089 2040 The @13`fill@ in example 3 does nothing because no extra space is added. 2090 2041 2091 \begin{cfa}[numbers=left ]2042 \begin{cfa}[numbers=left,xleftmargin=2.5\parindentlnth] 2092 2043 int * ia = alloc( 5, @5`fill@ ); for ( i; 5 ) sout | ia[i]; sout | nl; 2093 2044 ia = alloc( 10, @ia`realloc@, @7`fill@ ); for ( i; 10 ) sout | ia[i]; sout | nl; … … 2095 2046 ia = alloc( 3, @ia`realloc@, @4096`align@, @2`fill@ ); sout | ia; for ( i; 3 ) sout | &ia[i] | ia[i]; sout | nl; 2096 2047 \end{cfa} 2097 \begin{lstlisting}[numbers=left ]2048 \begin{lstlisting}[numbers=left,xleftmargin=2.5\parindentlnth] 2098 2049 5 5 5 5 5 2099 2050 5 5 5 5 5 7 7 7 7 7 -
doc/proposals/enum.tex
rc75b30a r32490deb 7 7 \usepackage{graphics} 8 8 \usepackage{xspace} 9 \usepackage{relsize} % must be after change to small or selects old size 10 \usepackage{calc} % latex arithmetic 9 11 10 12 \makeatletter … … 22 24 \newcommand{\@newterm}[2][\@empty]{\lowercase{\def\temp{#2}}{\newtermFontInline{#2}}\ifx#1\@empty\index{\temp}\else\index{#1@{\protect#2}}\fi} 23 25 \newcommand{\@snewterm}[2][\@empty]{{\newtermFontInline{#2}}\ifx#1\@empty\index{#2}\else\index{#1@{\protect#2}}\fi} 26 27 \newcommand{\LstBasicStyle}[1]{{\lst@basicstyle{#1}}} 28 \newcommand{\LstKeywordStyle}[1]{{\lst@basicstyle{\lst@keywordstyle{#1}}}} 29 \newcommand{\LstCommentStyle}[1]{{\lst@basicstyle{\lst@commentstyle{#1}}}} 30 \newcommand{\LstStringStyle}[1]{{\lst@basicstyle{\lst@stringstyle{#1}}}} 31 \newcommand{\LstNumberStyle}[1]{{\lst@basicstyle{\lst@numberstyle{#1}}}} 32 33 \newlength{\gcolumnposn} % temporary hack because lstlisting does not handle tabs correctly 34 \newlength{\columnposn} 35 \setlength{\gcolumnposn}{3in} 36 \setlength{\columnposn}{\gcolumnposn} 37 \newcommand{\setgcolumn}[1]{\global\gcolumnposn=#1\global\columnposn=\gcolumnposn} 38 \newcommand{\C}[2][\@empty]{\ifx#1\@empty\else\global\setlength{\columnposn}{#1}\global\columnposn=\columnposn\fi\hfill\makebox[\textwidth-\columnposn][l]{\LstCommentStyle{#2}}} 39 \newcommand{\CD}[2][\@empty]{\ifx#1\@empty\else\global\setlength{\columnposn}{#1}\global\columnposn=\columnposn\fi\hfill\makebox[\textwidth-\columnposn][l]{\LstBasicStyle{#2}}} 40 \newcommand{\CRT}{\global\columnposn=\gcolumnposn} 24 41 \makeatother 25 42 … … 48 65 \newcommand{\CCIcon}{\textrm{C}\kern-.1em\hbox{+\kern-.25em+}} % C++ icon 49 66 \newcommand{\CC}[1][]{\protect\CCIcon{#1}\xspace} % C++ symbolic name 67 \newcommand{\Csharp}{C\raisebox{-0.7ex}{\relsize{2}$^\sharp$}\xspace} % C# symbolic name 50 68 \newcommand{\PAB}[1]{{\color{red}PAB: #1}} 51 69 … … 56 74 57 75 \lstdefinestyle{CStyle}{ 58 % backgroundcolor=\color{backgroundColour}, 76 % backgroundcolor=\color{backgroundColour}, 59 77 % commentstyle=\color{mGreen}, 60 78 % keywordstyle=\color{magenta}, … … 64 82 basicstyle=\small\linespread{0.9}\sf, % reduce line spacing and use sanserif font 65 83 % basicstyle=\footnotesize, 66 breakatwhitespace=false, 67 % breaklines=true, 68 captionpos=b, 69 keepspaces=true, 84 breakatwhitespace=false, 85 % breaklines=true, 86 captionpos=b, 87 keepspaces=true, 70 88 escapechar=\$, % LaTeX escape in CFA code 71 % numbers=left, 72 % numbersep=5pt, 89 % numbers=left, 90 % numbersep=5pt, 73 91 % numberstyle=\tiny\color{mGray}, 74 % showspaces=false, 92 % showspaces=false, 75 93 showstringspaces=false, 76 % showtabs=false, 94 % showtabs=false, 77 95 showlines=true, % show blank lines at end of code 78 96 tabsize=5, … … 93 111 94 112 \begin{abstract} 95 An enumeration is a type that defines a list of named constant values in C (and other languages). 96 C and \CC use an integral type as the underlying representation of an enumeration. 97 \CFA extends C enumerations to allow all basic and custom types for the inner representation. 113 An enumeration is a type defining an ordered set of named constant values, where a name abstracts a value, e.g., @PI@ versus @3.145159@. 114 C restrict an enumeration type to the integral type @signed int@, which \CC support , meaning enumeration names bind to integer constants. 115 \CFA extends C enumerations to allow all basic and custom types for the enumeration type, like other modern programming languages. 116 Furthermore, \CFA adds other useful features for enumerations to support better software-engineering practices and simplify program development. 98 117 \end{abstract} 99 118 119 \section{Background} 120 121 Naming values is a common practice in mathematics and engineering, e.g., $\pi$, $\tau$ (2$\pi$), $\phi$ (golden ratio), MHz (1E6), etc. 122 Naming is also commonly used to represent many other numerical phenomenon, such as days of the week, months of a year, floors of a building (basement), time (noon, New Years). 123 Many programming languages capture this important capability through a mechanism called an \newterm{enumeration}. 124 An enumeration is similar to other programming-language types by providing a set of constrained values, but adds the ability to name \emph{all} the values in its set. 125 Note, all enumeration names must be unique but different names can represent the same value (eight note, quaver), which are synonyms. 126 127 Specifically, an enumerated type is a type whose values are restricted to a fixed set of named constants. 128 Fundamentally, all types are restricted to a fixed set of values because of the underlying von Neumann architecture, and hence, to a corresponding set of constants, e.g., @3@, @3.5@, @3.5+2.1i@, @'c'@, @"abc"@, etc. 129 However, the values for basic types are not named, other than the programming-language supplied constants. 130 131 100 132 \section{C-Style Enum} 101 133 102 \CFA supports the C-Style enumeration using the samesyntax and semantics.134 The C-Style enumeration has the following syntax and semantics. 103 135 \begin{lstlisting}[label=lst:weekday] 104 enum Weekday { Monday, Tuesday, Wednesday, Thursday =10, Friday, Saturday, Sunday };105 $\(\uparrow\)$ $\(\uparrow\)$106 ${\rm \newterm{enumeration name}}$ ${\rm \newterm{enumerator names}}107 \end{lstlisting} 108 The example defines an enumeration type @Weekday@ with ordered enumerators @Monday@, @Tuesday@, @Wednesday@, @Thursday@, @Friday@, @Saturday@ and @Sunday@.136 enum Weekday { Monday, Tuesday, Wednesday, Thursday@ = 10@, Friday, Saturday, Sunday }; 137 $\(\uparrow\)$ $\(\uparrow\)$ 138 ${\rm \newterm{enumeration name}}$ ${\rm \newterm{enumerator names}} 139 \end{lstlisting} 140 Here, the enumeration type @Weekday@ defines the ordered \newterm{enumerator}s @Monday@, @Tuesday@, @Wednesday@, @Thursday@, @Friday@, @Saturday@ and @Sunday@. 109 141 The successor of @Tuesday@ is @Monday@ and the predecessor of @Tuesday@ is @Wednesday@. 110 A C enumeration is an integral type, with consecutive enumerator values assigned by the compiler starting at zero or the next explicitly initialized value by the programmer.111 For example, @Monday@ to @Wednesday@ have values 0--2 implicitly set by the compiler, @Thursday@ is explicitly set to @10@ by the programmer, and @Friday@ to @Sunday@ have values 11--13 implicitly set by the compiler.142 A C enumeration is implemented by an integral type, with consecutive enumerator values assigned by the compiler starting at zero or the next explicitly initialized value. 143 For example, @Monday@ to @Wednesday@ have values 0--2 implicitly set by the compiler, @Thursday@ is explicitly set to @10@, and @Friday@ to @Sunday@ have values 11--13 implicitly set by the compiler. 112 144 113 145 There are 3 attributes for an enumeration: \newterm{position}, \newterm{label}, and \newterm{value}: … … 118 150 \it position & 0 & 1 & 2 & 3 & 4 & 5 & 6 \\ 119 151 \it label & Monday & Tuesday & Wednesday & Thursday & Friday & Saturday & Sunday \\ 120 \it value & 0 & 1 & 2 & 10& 11 & 12 & 13152 \it value & 0 & 1 & 2 & {\color{red}10}& 11 & 12 & 13 121 153 \end{tabular} 122 154 \end{cquote} 123 155 124 156 The enumerators of an enumeration are unscoped, i.e., enumerators declared inside of an @enum@ are visible in the enclosing scope of the @enum@ type. 157 Furthermore, there is an implicit bidirectional conversion between an enumeration and integral types. 125 158 \begin{lstlisting}[label=lst:enum_scope] 126 159 { 127 enum Weekday { ... }; // enumerators implicitly projected into local scope160 enum Weekday { ... }; $\C{// enumerators implicitly projected into local scope}$ 128 161 Weekday weekday = Monday; 129 weekday = Friday; 130 int i = Sunday // i == 13 162 weekday = Friday; $\C{// weekday == 11}$ 163 int i = Sunday $\C{// i == 13}$ 164 weekday = 10000; $\C{// undefined behaviour}$ 131 165 } 132 int j = Wednesday; // ERROR! Wednesday is not declared in this scope166 int j = Wednesday; $\C{// ERROR! Wednesday is not declared in this scope}$ 133 167 \end{lstlisting} 134 168 135 169 \section{\CFA-Style Enum} 136 170 137 A \CFA enumeration is parameterized by a type specifying each enumerator's type. 138 \CFA allows any object type for the enumerators, and values assigned to enumerators must be from the declared type. 171 \CFA supports C-Style enumeration using the same syntax and semantics for backwards compatibility. 172 \CFA also extends C-Style enumeration by adding a number of new features that bring enumerations inline with other modern programming languages. 173 174 \subsection{Enumerator Typing} 175 176 \CFA extends the enumeration by parameterizing the enumeration with a type for the enumerators, allowing enumerators to be assigned any values from the declared type. 139 177 \begin{lstlisting}[label=lst:color] 140 enum Colour( @char *@ ) { Red = "R", Green = "G", Blue = "B" }; 141 \end{lstlisting} 142 The type of @Colour@ is @char *@ and each enumerator is initialized with a C string. 143 Only types with a defined ordering can be automatically initialized (see Section~\ref{s:AutoInitializable}). 178 enum( @char@ ) Currency { Dollar = '$\textdollar$', Euro = '$\texteuro$', Pound = '$\textsterling$' }; 179 enum( @double@ ) Planet { Venus = 4.87, Earth = 5.97, Mars = 0.642 }; // mass 180 enum( @char *@ ) Colour { Red = "red", Green = "green", Blue = "blue" }; 181 enum( @Currency@ ) Europe { Euro = '$\texteuro$', Pound = '$\textsterling$' }; // intersection 182 \end{lstlisting} 183 The types of the enumerators are @char@, @double@, and @char *@ and each enumerator is initialized with corresponding type values. 184 % Only types with a defined ordering can be automatically initialized (see Section~\ref{s:AutoInitializable}). 144 185 145 186 % An instance of \CFA-enum (denoted as @<enum_instance>@) is a label for the defined enum name. … … 151 192 A \CFA-enum can be scoped, meaning the enumerator constants are not projected into the enclosing scope. 152 193 \begin{lstlisting} 153 enum Colour( char * ) @!@ { ... }; 194 enum Weekday @!@ { /* as above */ }; 195 enum Colour( char * ) @!@ { /* as above */ }; 154 196 \end{lstlisting} 155 197 where the @'!'@ implies the enumerators are \emph{not} projected. … … 158 200 % $$<qualified\_expression> := <enum\_type>.<enumerator>$$ 159 201 \begin{lstlisting} 160 Colour colour = @Colour.@Red; // qualification 202 Weekday weekday = @Weekday.Monday@; $\C{// qualification}$ 203 Colour colour = @Colour.@Red; 161 204 colour = @Colour.@Blue; 162 205 \end{lstlisting} 163 206 164 \section{Enumeration Pseudo-functions} 165 Pseudo-functions are function-like operators that do not result in any run-time computations, i.e., like @sizeof@. Instead, the call to functions will be substituted into other expressions in compilation time. 166 167 \subsection{Enumerator Attributes} 168 The attributes of an enumerator are accessed by pseudo-functions @position@, @value@, and @label@. 207 \subsection{Enumeration Pseudo-functions} 208 209 Pseudo-functions are function-like operators that do not result in any run-time computations, i.e., like @sizeof@. 210 Often a call to a pseudo-function is substituted with information extracted from the symbol table at compilation time, like storage size or alignment associated with the underlying architecture.. 211 212 \subsubsection{Enumerator Attributes} 213 The attributes of an enumerator are accessed by pseudo-functions @position@, @value@, and @label@. 169 214 \begin{lstlisting} 170 int green_pos = @position@( Colour.Green ); // 1 171 char * green_value = @value@( Colour.Green ); / "G" 172 char * green_label = @label@( Colour.Green ); // "Green" 173 \end{lstlisting} 174 175 \subsection{enumerate()} 215 int green_pos = @position@( Colour.Green ); $\C{// 1}$ 216 char * green_value = @value@( Colour.Green ); $\C{// "G"}$ 217 char * green_label = @label@( Colour.Green ); $\C{// "Green"}$ 218 \end{lstlisting} 219 220 Enumeration Greek may have more or less enumerators than Letter, but the enumerator values must be from Letter. 221 Therefore, Greek enumerators are a subset of type Letter and are type compatible with enumeration Letter, but Letter enumerators are not type compatible with enumeration Greek. 222 223 \subsubsection{\lstinline{enumerate()}} 224 176 225 \begin{lstlisting}[label=lst:c_switch] 177 226 enum(int) C_ENUM { First, Second, Third = First, Fourth }; 178 int v(C_ENUM e) { 179 switch( e ) { 180 case First: return 0; break; 181 case Second: return 1; break; 182 // case Thrid: return 2; break; 183 // case Fourth: return 3; break; 184 }; 185 }; 186 \end{lstlisting} 187 In the @C_ENUM@ example, @Third@ is an alias of @First@ and @Fourth@ is an alias of @Second@. Programmers cannot make case branches for @Third@ and @Fourth@ because the switch statement matches cases by the enumerator's value. Case First and Third, or Second and Fourth, has duplicate case values. 188 189 @enumerate()@ is a pseudo-function that makes the switch statement match by an enumerator instead. 227 int v( C_ENUM e ) { 228 switch( e ) { 229 case First: return 0; break; 230 case Second: return 1; break; 231 // case Third: return 2; break; 232 // case Fourth: return 3; break; 233 }; 234 }; 235 \end{lstlisting} 236 In the @C_ENUM@ example, @Third@ is an alias of @First@ and @Fourth@ is an alias of @Second@. 237 Programmers cannot make case branches for @Third@ and @Fourth@ because the switch statement matches cases by the enumerator's value. 238 Case @First@ and @Third@, or @Second@ and @Fourth@, has duplicate case values. 239 240 @enumerate()@ is a pseudo-function that makes the switch statement match by an enumerator instead. 190 241 \begin{lstlisting}[label=lst:c_switch_enumerate] 191 242 enum(double) C_ENUM { First, Second, Third = First, Fourth }; 192 C_ENUM variable_a = First, variable_b = Second, variable_c = Th rid, variable_d = Fourth;193 int v(C_ENUM e) { 194 195 196 197 case Thrid: return label( e ); break;198 199 243 C_ENUM variable_a = First, variable_b = Second, variable_c = Third, variable_d = Fourth; 244 int v(C_ENUM e) { 245 switch( enumeratate( e ) ) { 246 case First: return e; break; 247 case Second: return value( e ); break; 248 case Third: return label( e ); break; 249 case Fourth: return position( e ); break; 250 }; 200 251 }; 201 252 p(variable_a); // 0 … … 205 256 \end{lstlisting} 206 257 258 207 259 \section{Enumeration Storage} 260 208 261 209 262 \subsection{Enumeration Variable} … … 228 281 >>> label( Colour, 1) -> char * 229 282 \end{lstlisting} 230 @T@ represents the type declared in the \CFA enumeration defined and @char *@ in the example. 283 @T@ represents the type declared in the \CFA enumeration defined and @char *@ in the example. 231 284 These generated functions are $Companion Functions$, they take an $companion$ object and the position as parameters. 232 285 286 233 287 \subsection{Enumeration Data} 288 234 289 \begin{lstlisting}[label=lst:enumeration_backing_data] 235 290 enum(T) E { ... }; 236 291 // backing data 237 T* E_values; 238 char** E_labels; 239 \end{lstlisting} 240 Storing values and labels as arrays can sometimes help support enumeration features. However, the data structures are the overhead for the programs. We want to reduce the memory usage for enumeration support by: 292 T * E_values; 293 char ** E_labels; 294 \end{lstlisting} 295 Storing values and labels as arrays can sometimes help support enumeration features. 296 However, the data structures are the overhead for the programs. We want to reduce the memory usage for enumeration support by: 241 297 \begin{itemize} 242 \item Only generates the data array if necessary 243 \item The compilation units share the data structures. No extra overhead if the data structures are requested multiple times. 298 \item Only generates the data array if necessary 299 \item The compilation units share the data structures. 300 No extra overhead if the data structures are requested multiple times. 244 301 \end{itemize} 245 302 246 303 247 \248 304 \section{Unification} 249 305 250 306 \subsection{Enumeration as Value} 251 307 \label{section:enumeration_as_value} 252 An \CFA enumeration with base type T can be used seamlessly as T, without explicitly calling the pseudo-function value. 308 An \CFA enumeration with base type T can be used seamlessly as T, without explicitly calling the pseudo-function value. 253 309 \begin{lstlisting}[label=lst:implicit_conversion] 254 310 char * green_value = Colour.Green; // "G" 255 // Is equivalent to 311 // Is equivalent to 256 312 // char * green_value = value( Color.Green ); "G" 257 313 \end{lstlisting} 258 314 315 259 316 \subsection{Unification Distance} 317 260 318 \begin{lstlisting}[label=lst:unification_distance_example] 261 319 T_2 Foo(T1); … … 265 323 @path(A, B)@ is a compiler concept that returns one of the following: 266 324 \begin{itemize} 267 268 \item Safe, if B can be used as A without losing its precision, or B is a subtype of A. 269 270 325 \item Zero or 0, if and only if $A == B$. 326 \item Safe, if B can be used as A without losing its precision, or B is a subtype of A. 327 \item Unsafe, if B loses its precision when used as A, or A is a subtype of B. 328 \item Infinite, if B cannot be used as A. A is not a subtype of B and B is not a subtype of A. 271 329 \end{itemize} 272 330 … … 278 336 The arithmetic of distance is the following: 279 337 \begin{itemize} 280 281 \item $Safe * k < Unsafe$, for finite k. 282 283 338 \item $Zero + v= v$, for some value v. 339 \item $Safe * k < Unsafe$, for finite k. 340 \item $Unsafe * k < Infinite$, for finite k. 341 \item $Infinite + v = Infinite$, for some value v. 284 342 \end{itemize} 285 343 … … 288 346 289 347 \subsection{Variable Overloading and Parameter Unification} 348 290 349 \CFA allows variable names to be overloaded. It is possible to overload a variable that has type T and an enumeration with type T. 291 350 \begin{lstlisting}[label=lst:variable_overload] … … 304 363 Similarly, functions can be overloaded with different signatures. \CFA picks the correct function entity based on the distance between parameter types and the arguments. 305 364 \begin{lstlisting}[label=lst:function_overload] 306 Colour green = Colour.Green; 365 Colour green = Colour.Green; 307 366 void foo(Colour c) { sout | "It is an enum"; } // First foo 308 367 void foo(char * s) { sout | "It is a string"; } // Second foo … … 326 385 % The @EnumInstType@ is convertible to other types. 327 386 % A \CFA enumeration expression is implicitly \emph{overloaded} with its three different attributes: value, position, and label. 328 % The \CFA compilers need to resolve an @EnumInstType@ as one of its attributes based on the current context. 387 % The \CFA compilers need to resolve an @EnumInstType@ as one of its attributes based on the current context. 329 388 330 389 % \begin{lstlisting}[caption={Null Context}, label=lst:null_context] … … 379 438 % } 380 439 % \end{lstlisting} 381 % % The conversion can work backward: in restrictive cases, attributes of can be implicitly converted back to the EnumInstType. 440 % % The conversion can work backward: in restrictive cases, attributes of can be implicitly converted back to the EnumInstType. 382 441 % Backward conversion: 383 442 % \begin{lstlisting}[caption={Unification Functions}, label=lst:unification_func_call] … … 389 448 % \begin{lstlisting}[caption={Unification Functions}, label=lst:unification_func_call] 390 449 % { 391 % 450 % Unification( EnumInstType<Colour>, int ) >>> label 392 451 % } 393 452 % \end{lstlisting} 394 453 % @int@ can be unified with the label of Colour. 395 % @5@ is a constant expression $\Rightarrow$ Compiler knows the value during the compilation $\Rightarrow$ turns it into 454 % @5@ is a constant expression $\Rightarrow$ Compiler knows the value during the compilation $\Rightarrow$ turns it into 396 455 % \begin{lstlisting} 397 456 % { 398 % enum Colour colour = Colour.Green;457 % enum Colour colour = Colour.Green; 399 458 % } 400 459 % \end{lstlisting} … … 411 470 % { 412 471 % enum T (int) { ... } // Declaration 413 % enum T t = 1; 472 % enum T t = 1; 414 473 % } 415 474 % \end{lstlisting} … … 423 482 % return the FIRST enumeration constant that has the value 1, by searching through the values array 424 483 % \end{enumerate} 425 % The downside of the precedence rule: @EnumInstType@ $\Rightarrow$ @int ( value )@ $\Rightarrow$ @EnumInstType@ may return a different @EnumInstType@ because the value can be repeated and there is no way to know which one is expected $\Rightarrow$ want uniqueness 484 % The downside of the precedence rule: @EnumInstType@ $\Rightarrow$ @int ( value )@ $\Rightarrow$ @EnumInstType@ may return a different @EnumInstType@ because the value can be repeated and there is no way to know which one is expected $\Rightarrow$ want uniqueness 426 485 427 486 % \subsection{Casting} … … 431 490 % (int) Foo.A; 432 491 % \end{lstlisting} 433 % The \CFA-compiler unifies @EnumInstType<int>@ with int, with returns @value( Foo.A )@, which has statically known value 10. In other words, \CFA-compiler is aware of a cast expression, and it forms the context for EnumInstType resolution. The expression with type @EnumInstType<int>@ can be replaced by the compile with a constant expression 10, and optionally discard the cast expression. 492 % The \CFA-compiler unifies @EnumInstType<int>@ with int, with returns @value( Foo.A )@, which has statically known value 10. In other words, \CFA-compiler is aware of a cast expression, and it forms the context for EnumInstType resolution. The expression with type @EnumInstType<int>@ can be replaced by the compile with a constant expression 10, and optionally discard the cast expression. 434 493 435 494 % \subsection{Value Conversion} … … 445 504 % int j = value( Foo, a ) 446 505 % \end{lstlisting} 447 % Similarly, the generated code for the third line is 506 % Similarly, the generated code for the third line is 448 507 % \begin{lstlisting} 449 508 % char * j = label( Foo, a ) … … 455 514 456 515 \subsection{C Enumeration Rule} 457 A C enumeration has an integral type. If not initialized, the first enumerator implicitly has the integral value 0, and other enumerators have a value equal to its $predecessor + 1$. 516 A C enumeration has an integral type. If not initialized, the first enumerator implicitly has the integral value 0, and other enumerators have a value equal to its $predecessor + 1$. 458 517 459 518 \subsection{Auto Initializable} … … 478 537 Odd ?++( Odd t1 ) { return Odd( t1.i + 2); }; 479 538 \end{lstlisting} 480 When the type of an enumeration is @AutoInitializable@, implicit initialization is available. 539 When the type of an enumeration is @AutoInitializable@, implicit initialization is available. 481 540 \begin{lstlisting}[label=lst:sample_auto_Initializable_usage] 482 541 enum AutoInitUsage(Odd) { … … 514 573 @alph@ is the iterating enumeration object, which returns the value of an @Alphabet@ in this context according to the precedence rule. 515 574 516 \textbullet\ \CFA offers a shorthand for iterating all enumeration constants: 575 \textbullet\ \CFA offers a shorthand for iterating all enumeration constants: 517 576 \begin{lstlisting}[label=lst:range_functions] 518 577 for ( Alphabet alph ) { sout | alph; } … … 567 626 >>> 10 11 12 13 14 15 16 17 18 568 627 \end{lstlisting} 569 The first syntax is stepping to the next enumeration constant, which is the default stepping scheme if not explicitly specified. The second syntax, on the other hand, is to call @operator+=@ @one_type@ on the @value( s )@. Therefore, the second syntax is equivalent to 628 The first syntax is stepping to the next enumeration constant, which is the default stepping scheme if not explicitly specified. The second syntax, on the other hand, is to call @operator+=@ @one_type@ on the @value( s )@. Therefore, the second syntax is equivalent to 570 629 \begin{lstlisting}[label=lst:range_function_stepping_converted] 571 630 for ( typeof( value(Sequence.A) ) s=value( Sequence.A ); s <= Sequence.D; s+=1 ) { sout | alph; } … … 579 638 for ( char * alph; Alphabet ) 580 639 \end{lstlisting} 581 This for-loop implicitly iterates every label of the enumeration, because a label is the only valid resolution to the chwith type @char *@ in this case.640 This for-loop implicitly iterates every label of the enumeration, because a label is the only valid resolution to @ch@ with type @char *@ in this case. 582 641 If the value can also be resolved as the @char *@, you might iterate the labels explicitly with the array iteration. 583 642 \begin{lstlisting}[label=lst:range_functions_label_implicit] … … 591 650 % \begin{lstlisting} 592 651 % enum T( int, char * ) { 593 % 652 % a=42, b="Hello World" 594 653 % }; 595 654 % \end{lstlisting} 596 % The enum T declares two different types: int and char *. The enumerators of T hold values of one of the declared types. 655 % The enum T declares two different types: int and char *. The enumerators of T hold values of one of the declared types. 597 656 598 657 \subsection{Enumeration Inheritance} … … 602 661 enum /* inferred */ Name2 { inline Name, Sue = "Sue", Tom = "Tom" }; 603 662 \end{lstlisting} 604 \lstinline{Inline} allows Enumeration Name2 to inherit enumerators from Name1 by containment, and a Name enumeration is a subtype of enumeration Name2. An enumeration instance of type Name can be used where an instance of Name2 is expected. 663 \lstinline{Inline} allows Enumeration Name2 to inherit enumerators from Name1 by containment, and a Name enumeration is a subtype of enumeration Name2. An enumeration instance of type Name can be used where an instance of Name2 is expected. 605 664 \begin{lstlisting}[label=lst:EnumInline] 606 665 Name Fred; … … 610 669 If enumeration A declares @inline B@ in its enumeration body, enumeration A is the "inlining enum" and enumeration B is the "inlined enum". 611 670 612 An enumeration can inline at most one other enumeration. The inline declaration must be placed before the first enumerator of the inlining enum. The inlining enum has all the enumerators from the inlined enum, with the same labels, values, and position. 671 An enumeration can inline at most one other enumeration. The inline declaration must be placed before the first enumerator of the inlining enum. The inlining enum has all the enumerators from the inlined enum, with the same labels, values, and position. 613 672 \begin{lstlisting}[label=lst:EnumInline] 614 673 enum /* inferred */ Name2 { inline Name, Sue = "Sue", Tom = "Tom" }; … … 625 684 \begin{lstlisting}[label=lst:static_attr] 626 685 enum( char * ) Colour { 627 Red = "red", Blue = "blue", Green = "green" 628 }; 629 \end{lstlisting} 630 An enumerator expression returns its enumerator value as a constant expression with no runtime cost. For example, @Colour.Red@ is equivalent to the constant expression "red", and \CFA finishes the expression evaluation before generating the corresponding C code. Applying a pseudo-function to a constant enumerator expression results in a constant expression as well. @value( Colour.Red )@, @position( Colour. Red )@, and @label( Colour.Red )@ are equivalent to constant expression with char * value "red", int value 0, and char * value "Red", respectively. 686 Red = "red", Blue = "blue", Green = "green" 687 }; 688 \end{lstlisting} 689 An enumerator expression returns its enumerator value as a constant expression with no runtime cost. For example, @Colour.Red@ is equivalent to the constant expression "red", and \CFA finishes the expression evaluation before generating the corresponding C code. Applying a pseudo-function to a constant enumerator expression results in a constant expression as well. @value( Colour.Red )@, @position( Colour. Red )@, and @label( Colour.Red )@ are equivalent to constant expression with char * value "red", int value 0, and char * value "Red", respectively. 631 690 632 691 \subsection{Runtime Attribute Expression and Weak Referenced Data} … … 638 697 An enumeration variable c is equivalent to an integer variable with the value of @position( c )@ In Example~\ref{lst:dynamic_attr}, the value of enumeration variable c is unknown at compile time. In this case, the pseudo-function calls are reduced to expression that returns the enumerator values at runtime. 639 698 640 \CFA stores the variables and labels in const arrays to provide runtime lookup for enumeration information.699 \CFA stores the variables and labels in @const@ arrays to provide runtime lookup for enumeration information. 641 700 642 701 \begin{lstlisting}[label=lst:attr_array] … … 651 710 \end{lstlisting} 652 711 653 To avoid unnecessary memory usage, the labels and values array are only generated as needed, and only generate once across all compilation units. By default, \CFA defers the declaration of the label and value arrays until an call to attribute function with a dynamic value. If an attribute function is never called on a dynamic value of an enumerator, the array will never be allocated. Once the arrays are created, all compilation units share a weak reference to the allocation array. 712 To avoid unnecessary memory usage, the labels and values array are only generated as needed, and only generate once across all compilation units. By default, \CFA defers the declaration of the label and value arrays until an call to attribute function with a dynamic value. If an attribute function is never called on a dynamic value of an enumerator, the array will never be allocated. Once the arrays are created, all compilation units share a weak reference to the allocation array. 654 713 655 714 \subsection{Enum Prelude} … … 657 716 \begin{lstlisting}[label=lst:enum_func_dec] 658 717 forall( T ) { 659 660 661 718 unsigned position( unsigned ); 719 T value( unsigned ); 720 char * label( unsigned ); 662 721 } 663 722 \end{lstlisting} … … 670 729 forall(T) 671 730 class EnumDecl { 672 673 731 T* values; 732 char** label; 674 733 }; 675 734 \end{lstlisting} … … 679 738 \begin{lstlisting}[label=lst:EnumInstType] 680 739 class EnumInstType { 681 682 740 EnumDecl enumDecl; 741 int position; 683 742 }; 684 743 \end{lstlisting} … … 700 759 % struct Companion { 701 760 % const T * const values; 702 % 761 % const char * label; 703 762 % int length; 704 763 % }; … … 706 765 % \CFA generates companion objects, an instance of structure that encloses @necessary@ data to represent an enumeration. The size of the companion is unknown at the compilation time, and it "grows" in size to compensate for the @usage@. 707 766 708 % The companion object is singleton across the compilation (investigation). 767 % The companion object is singleton across the compilation (investigation). 709 768 710 769 % \CFA generates the definition of companion functions. … … 727 786 \begin{lstlisting}[label=lst:companion_trait] 728 787 forall(T1) { 729 730 731 732 733 788 trait Companion(otype T2<otype T1>) { 789 T1 value((otype T2<otype T1> const &); 790 int position(otype T2<otype T1> const &); 791 char * label(otype T2<otype T1> const &); 792 } 734 793 } 735 794 \end{lstlisting} … … 743 802 \begin{lstlisting} 744 803 enum(int) Weekday { 745 804 Monday=10, Tuesday, ... 746 805 }; 747 806 … … 758 817 \subsection{User Define Enumeration Functions} 759 818 760 Companion objects make extending features for \CFA enumeration easy. 819 Companion objects make extending features for \CFA enumeration easy. 761 820 \begin{lstlisting}[label=lst:companion_user_definition] 762 char * charastic_string( Companion o, int position ) { 763 return sprintf( "Label: %s; Value: %s", label( o, position ), value( o, position) ); 821 char * charastic_string( Companion o, int position ) { 822 return sprintf( "Label: %s; Value: %s", label( o, position ), value( o, position) ); 764 823 } 765 824 printf( charactic_string ( Color, 1 ) ); … … 776 835 Similarly, the user can work with the enumeration type itself: (see section ref...) 777 836 \begin{lstlisting}[ label=lst:companion_user_definition] 778 void print_enumerators ( Companion o ) { 837 void print_enumerators ( Companion o ) { 779 838 for ( c : Companion o ) { 780 839 sout | label (c) | value( c ) ; 781 } 840 } 782 841 } 783 842 print_enumerators( Colour ); … … 795 854 It ensures that the name of an enumerator is unique within the enumeration body, and checks if all values of the enumerator have the declaration type. 796 855 If the declared type is not @AutoInitializable@, \CFA rejects the enumeration definition. 797 Otherwise, it attempts to initialize enumerators with the enumeration initialization pattern. (a reference to a future initialization pattern section) 856 Otherwise, it attempts to initialize enumerators with the enumeration initialization pattern. (a reference to a future initialization pattern section) 798 857 799 858 \begin{lstlisting}[label=lst:init] … … 803 862 T ?+?( T & lhs, T & rhs ) { ... }; 804 863 805 enum (T) Sample { 806 Zero: 0 /* zero_t */, 864 enum (T) Sample { 865 Zero: 0 /* zero_t */, 807 866 One: Zero + 1 /* ?+?( Zero, one_t ) */ , ... 808 867 }; … … 826 885 \subsection{Qualified Expression} 827 886 828 \CFA uses qualified expression to address the scoping of \CFA-enumeration. 887 \CFA uses qualified expression to address the scoping of \CFA-enumeration. 829 888 \begin{lstlisting}[label=lst:qualified_expression] 830 889 aggregation_name.field; … … 837 896 838 897 \subsection{\lstinline{with} Clause/Statement} 898 839 899 Instead of qualifying an enumeration expression every time, the @with@ can be used to expose enumerators to the current scope, making them directly accessible. 840 900 \begin{lstlisting}[label=lst:declaration] … … 842 902 enum Animal( int ) { Cat=10, Dog=20 }; 843 903 with ( Color, Animal ) { 844 845 904 char * red_string = Red; // value( Color.Red ) 905 int cat = Cat; // value( Animal.Cat ) 846 906 } 847 907 \end{lstlisting} … … 851 911 enum RGB( int ) { Red=0, Green=1, Blue=2 }; 852 912 with ( Color, RGB ) { 853 // int red = Red; 913 // int red = Red; 854 914 } 855 915 \end{lstlisting} … … 865 925 The declaration \CFA-enumeration variable has the same syntax as the C-enumeration. Internally, such a variable will be represented as an EnumInstType. 866 926 927 \section{Related Work} 928 929 Enumerations exist in many popular programming languages, e.g., Pascal, Ada, \Csharp, \CC, Go, Java, Modula-3, Rust, Swift, Python, and Algebraic data type in functional programming. 930 There are a large set of overlapping features for all the languages, but each language has its own unique restrictions and extensions. 931 932 \subsection{Pascal} 933 934 \subsection{Ada} 935 936 \subsection{\Csharp} 937 938 \subsection{\CC} 939 940 Because \CC is backwards compatible with C, it inherited C's enumerations, except there is no implicit conversion from an integral value to an enumeration; 941 hence, the values in a \CC enumeration can only be its enumerators. 942 943 \CC{11} extended enumeration with a scoped enumeration, \lstinline[language=c++]{enum class} (or \lstinline[language=c++]{enum struct}), where the enumerators are local to the enumeration and are accessed using type qualification, e.g., @Weekday::Monday@. 944 \CC{20} supports unscoped access with a \lstinline[language=c++]{using enum} declaration. 945 946 For both unscoped and scoped enumerations, the underlying type is an implementation-defined integral type that is large enough to hold all enumerated values; it does not have to be the smallest possible type. 947 The underlying integral type can be explicitly specified: 948 \begin{lstlisting}[language=c++,{moredelim=**[is][\color{red}]{@}{@}}] 949 enum class RGB : @long@ { Red, Green, Blue }; 950 enum class rgb : @char@ { Red = 'r', Green = 'g', Blue = 'b' }; 951 enum class srgb : @signed char@ { Red = -1, Green = 0, Blue = 1 }; 952 \end{lstlisting} 953 954 \subsection{Go} 955 956 \subsection{Java} 957 958 \subsection{Modula-3} 959 960 \subsection{Rust} 961 962 \subsection{Swift} 963 964 \subsection{Python} 965 966 \subsection{Algebraic Data Type} 867 967 868 968 \end{document} -
doc/uC++toCFA/Makefile
rc75b30a r32490deb 8 8 BibTeX = BIBINPUTS=../bibliography: && export BIBINPUTS && bibtex 9 9 10 MAKEFLAGS = --no-print-directory --silent #10 MAKEFLAGS = --no-print-directory # --silent 11 11 VPATH = ${Build} ${Figures} 12 12 -
doc/uC++toCFA/uC++toCFA.tex
rc75b30a r32490deb 11 11 %% Created On : Wed Apr 6 14:53:29 2016 12 12 %% Last Modified By : Peter A. Buhr 13 %% Last Modified On : Sun Oct 15 23:09:58 202314 %% Update Count : 59 2613 %% Last Modified On : Thu Jan 11 14:46:14 2024 14 %% Update Count : 5942 15 15 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 16 16 … … 428 428 \begin{uC++} 429 429 struct S { 430 int i = 0; 430 int i = 0; // cheat, implicit default constructor 431 431 int setter( int j ) { int t = i; i = j; return t; } 432 432 int getter() { return i; } … … 434 434 435 435 S s; 436 @s.@setter( 3 ); // object-oriented call 436 @s.@setter( 3 ); // object-oriented calls 437 437 int k = @s.@getter(); 438 438 \end{uC++} … … 442 442 int i; 443 443 }; 444 void ?{}( S & s ) { s.i = 0; } 444 void ?{}( S & s ) { s.i = 0; } // explicit default constructor 445 445 int setter( @S & s,@ int j ) @with(s)@ { int t = i; i = j; return t; } 446 446 int getter( @S & s@ ) @with(s)@ { return i; } 447 447 S s; 448 setter( @s,@ 3 ); // normal routine call 448 setter( @s,@ 3 ); // normal routine calls 449 449 int k = getter( @s@ ); 450 450 \end{cfa} … … 458 458 \begin{tabular}{l|l} 459 459 \begin{uC++} 460 460 461 struct S { 461 462 int i; 462 S( int i ) { S::i = i; cout << S::i << endl; }463 }; 464 @uNoCtor<S>@ s[10];463 S( int i ) { S::i = i; cout << "ctor " << S::i << endl; } 464 ~S() { S::i = i; cout << "dtor " << S::i << endl; } 465 }; 465 466 int main() { 466 for ( int i = 0; i < 10; i += 1 ) { 467 s[i].ctor( i ); 468 } 469 for ( int i = 0; i < 10; i += 1 ) { 470 cout << s[i]@->@i << endl; 471 } 472 } 473 \end{uC++} 474 & 475 \begin{cfa} 467 enum { N = 5 }; 468 @uNoCtor<S>@ s[N]; // no constructor calls 469 for ( int i = 0; i < N; i += 1 ) @s[i].ctor( i )@; 470 for ( int i = 0; i < N; i += 1 ) cout << s[i]@->@i << endl; 471 } 472 \end{uC++} 473 & 474 \begin{cfa} 475 #include @<raii.hfa>@ // uninit 476 476 struct S { 477 477 int i; 478 478 }; 479 void ?{}( S & s, int i ) { s.i = i; sout | s.i; }480 S s[10] @$\color{red}@$= {}@; 479 void ?{}( S & s, int i ) { s.i = i; sout | "ctor" | s.i; } 480 void ^?{}( S & s ) { sout | "dtor" | s.i; } 481 481 int main() { 482 for ( i; 10 ) { 483 ?{}( s[i], i ); // call constructor 484 } 485 for ( i; 10 ) { 486 sout | s[i]@.@i; // dot not arrow 487 } 482 enum { N = 5 }; 483 @uninit(S)@ s[N]; // no constructor calls 484 for ( i; N ) @s[i]{ i }@; 485 for ( i; N ) sout | s[i]@.@i; 488 486 } 489 487 \end{cfa} -
doc/user/user.tex
rc75b30a r32490deb 11 11 %% Created On : Wed Apr 6 14:53:29 2016 12 12 %% Last Modified By : Peter A. Buhr 13 %% Last Modified On : Sun Jan 14 17:27:41 202414 %% Update Count : 576413 %% Last Modified On : Tue Jan 30 09:02:41 2024 14 %% Update Count : 6046 15 15 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 16 16 … … 46 46 %\input{common} % common CFA document macros 47 47 \usepackage[dvips,plainpages=false,pdfpagelabels,pdfpagemode=UseNone,colorlinks=true,pagebackref=true,linkcolor=blue,citecolor=blue,urlcolor=blue,pagebackref=true,breaklinks=true]{hyperref} 48 \urlstyle{sf} 48 49 \usepackage{breakurl} 49 50 … … 163 164 164 165 \Index*[C++]{\CC{}}~\cite{c++:v1} had a similar goal 30 years ago, allowing object-oriented programming to be incrementally added to C. 165 However, \CC currently has the disadvantages of a strong object-oriented bias, multiple legacy design-choices that are difficult to update, and active divergence of the language model from C, requiring significant effort and training to incrementally add \CC to a C -based project.166 However, \CC currently has the disadvantages of a strong object-oriented bias, multiple legacy design-choices that are difficult to update, and active divergence of the language model from C, requiring significant effort and training to incrementally add \CC to a C code-base. 166 167 In contrast, \CFA has 30 years of hindsight and a clean starting point. 167 168 … … 200 201 \end{center} 201 202 While \CFA I/O \see{\VRef{s:StreamIOLibrary}} looks similar to \Index*[C++]{\CC{}}, there are important differences, such as automatic spacing between variables and an implicit newline at the end of the expression list, similar to \Index*{Python}~\cite{Python}. 203 In general, \CFA programs are 10\% to 30\% shorter than their equivalent C/\CC counterparts. 202 204 203 205 … … 218 220 Even with all its problems, C continues to be popular because it allows writing software at virtually any level in a computer system without restriction. 219 221 For system programming, where direct access to hardware, storage management, and real-time issues are a requirement, C is the only language of choice. 220 The TIOBE index~\cite{TIOBE} for February 202 1ranks the top six most \emph{popular} programming languages as C 17.4\%, \Index*{Java} 12\%, Python 12\%, \Index*[C++]{\CC{}} 7.6\%, \Csharp 4\%, Visual Basic 3.8\% = 56.8\%, where the next 50 languages are less than 2\% each, with a long tail.222 The TIOBE index~\cite{TIOBE} for February 2023 ranks the top six most \emph{popular} programming languages as C 17.4\%, \Index*{Java} 12\%, Python 12\%, \Index*[C++]{\CC{}} 7.6\%, \Csharp 4\%, Visual Basic 3.8\% = 56.8\%, where the next 50 languages are less than 2\% each, with a long tail. 221 223 The top 4 rankings over the past 35 years are: 222 224 \begin{center} … … 238 240 however, it largely extended the C language, and did not address many of C's existing problems.\footnote{% 239 241 Two important existing problems addressed were changing the type of character literals from ©int© to ©char© and enumerator from ©int© to the type of its enumerators.} 240 \Index*{Fortran}~\cite{Fortran08}, \Index*{Cobol}~\cite{Cobol14}, and \Index*{Ada}~\cite{Ada1 2} are examples of programming languages that took an evolutionary approach, where modern language-features (\eg objects, concurrency) are added and problems fixed within the framework of the existing language.242 \Index*{Fortran}~\cite{Fortran08}, \Index*{Cobol}~\cite{Cobol14}, and \Index*{Ada}~\cite{Ada16} are examples of programming languages that took an evolutionary approach, where modern language-features (\eg objects, concurrency) are added and problems fixed within the framework of the existing language. 241 243 \Index*{Java}~\cite{Java8}, \Index*{Go}~\cite{Go}, \Index*{Rust}~\cite{Rust} and \Index*{D}~\cite{D} are examples of the revolutionary approach for modernizing C/\CC, resulting in a new language rather than an extension of the descendent. 242 244 These languages have different syntax and semantics from C, do not interoperate directly with C, and are not systems languages because of restrictive memory-management or garbage collection. … … 263 265 % extending the C type system with parametric polymorphism and overloading, as opposed to the \Index*[C++]{\CC{}} approach of object-oriented extensions. 264 266 \CFA{}\hspace{1pt}'s polymorphism was originally formalized by \Index*{Glen Ditchfield}\index{Ditchfield, Glen}~\cite{Ditchfield92}, and first implemented by \Index*{Richard Bilson}\index{Bilson, Richard}~\cite{Bilson03}. 265 However, at that time, there was little interest ingin extending C, so work did not continue.267 However, at that time, there was little interest in extending C, so work did not continue. 266 268 As the saying goes, ``\Index*{What goes around, comes around.}'', and there is now renewed interest in the C programming language because of the legacy code-base, so the \CFA project was restarted in 2015. 267 269 … … 272 274 \CFA is designed to integrate directly with existing C programs and libraries. 273 275 The most important feature of \Index{interoperability} is using the same \Index{calling convention}s, so there is no complex interface or overhead to call existing C routines. 274 This feature allows \CFA programmers to take advantage of the existing panoply of C libraries to access thousands of externalsoftware features.276 This feature allows \CFA programmers to take advantage of the existing panoply of C libraries to access thousands of software features. 275 277 Language developers often state that adequate \Index{library support} takes more work than designing and implementing the language itself. 276 278 Fortunately, \CFA, like \Index*[C++]{\CC{}}, starts with immediate access to all exiting C libraries, and in many cases, can easily wrap library routines with simpler and safer interfaces, at zero or very low cost. … … 320 322 However, it is necessary to differentiate between C and \CFA code because of name \Index{overload}ing, as for \CC. 321 323 For example, the C math-library provides the following routines for computing the absolute value of the basic types: ©abs©, ©labs©, ©llabs©, ©fabs©, ©fabsf©, ©fabsl©, ©cabsf©, ©cabs©, and ©cabsl©. 322 Whereas, \CFA wraps each ofthese routines into one overloaded name ©abs©:323 \begin{cfa} 324 char ®abs®( char ); 325 extern "C" { int ®abs®( int ); } §\C{// use default C routine for int}§326 long int ®abs®( long int ); 327 long long int ®abs®( long long int ); 328 float ®abs®( float ); 329 double ®abs®( double ); 330 long double ®abs®( long double ); 331 float _Complex ®abs®( float _Complex ); 332 double _Complex ®abs®( double _Complex ); 333 long double _Complex ®abs®( long double _Complex ); 324 Whereas, \CFA wraps these routines into one overloaded name ©abs©: 325 \begin{cfa} 326 unsigned char ®abs®( signed char ); §\C[3.5in]{// no C equivalent}§ 327 extern "C" { int ®abs®( int ); } §\C{// C abs}§ 328 unsigned long int ®abs®( long int ); §\C{// C labs}§ 329 unsigned long long int ®abs®( long long int ); §\C{// C llabs}§ 330 float ®abs®( float ); §\C{// C fabsf}§ 331 double ®abs®( double ); §\C{// C fabs}§ 332 long double ®abs®( long double ); §\C{// C fabsl}§ 333 float _Complex ®abs®( float _Complex ); §\C{// C cabsf}§ 334 double _Complex ®abs®( double _Complex ); §\C{// C cabs}§ 335 long double _Complex ®abs®( long double _Complex ); §\C{// C cabsl}\CRT§ 334 336 \end{cfa} 335 337 The problem is a \Index{name clash} between the C name ©abs© and the \CFA names ©abs©, resulting in two name linkages\index{C linkage}: ©extern "C"© and ©extern "Cforall"© (default). … … 339 341 340 342 This example illustrates a core idea in \CFA: \emph{the \Index{power of a name}}. 341 The name ``©abs©'' evokes the notion of absolute value ,and many mathematical types provide the notion of absolute value.342 Hence, knowing the name ©abs© is sufficient to apply it to any type where it is applicable.343 The name ``©abs©'' evokes the notion of absolute value and many mathematical types provide the notion of absolute value. 344 Hence, knowing the name ©abs© is sufficient to apply it to any applicable type. 343 345 The time savings and safety of using one name uniformly versus $N$ unique names cannot be underestimated. 344 346 345 347 346 348 \section{\CFA Compilation} 349 350 \CFA is a \newterm{transpiler}, meaning it reads in a programming language (\CFA) as input and generates another programming language (C) as output, whereas a \newterm{compiler} reads in a programming language and generates assembler/machine code. 351 Hence, \CFA is like the C preprocessor modifying a program and sending it on to another step for further transformation. 352 The order of transformation is C preprocessor, \CFA, and finally GNU C compiler, which also has a number of transformation steps, such as assembler and linker. 347 353 348 354 The command ©cfa© is used to compile a \CFA program and is based on the \Index{GNU} \Indexc{gcc} command, \eg: … … 444 450 which conditionally includes the correct header file, if the program is compiled using \Indexc{gcc} or \Indexc{cfa}. 445 451 446 The \CFA translator has multiplesteps.447 The following flags control how the translator works, the stages run, and printing within a stage.452 The \CFA \Index{transpiler} has multiple internal steps. 453 The following flags control how the \CFA transpiler works, the stages run, and printing within a stage. 448 454 The majority of these flags are used by \CFA developers, but some are occasionally useful to programmers. 449 Each option must be escaped with \Indexc{-XCFA}\index{trans lator option!-XCFA@{©-XCFA©}} to direct it to the compilerstep, similar to the ©-Xlinker© flag for the linker, \eg:455 Each option must be escaped with \Indexc{-XCFA}\index{transpiler option!-XCFA@{©-XCFA©}} to direct it to the \CFA compilation step, similar to the ©-Xlinker© flag for the linker, \eg: 450 456 \begin{lstlisting}[language=sh] 451 457 cfa §test§.cfa -CFA -XCFA -p # print translated code without printing the standard prelude … … 458 464 \begin{description}[topsep=5pt,itemsep=0pt,parsep=0pt] 459 465 \item 460 \Indexc{-c}\index{trans lator option!-c@{©-c©}}, \Indexc{--colors}\index{translator option!--colors@{©--colors©}} \, diagnostic color: ©never©, ©always©, \lstinline[deletekeywords=auto]{auto}461 \item 462 \Indexc{-g}\index{trans lator option!-g@{©-g©}}, \Indexc{--gdb}\index{translator option!--gdb@{©--gdb©}} \, wait for gdb to attach463 \item 464 \Indexc{-h}\index{trans lator option!-h@{©-h©}}, \Indexc{--help}\index{translator option!--help@{©--help©}} \, print translator help message465 \item 466 \Indexc{-i}\index{trans lator option!-i@{©-i©}}, \Indexc{--invariant}\index{translator option!--invariant@{©--invariant©}} \, invariant checking during AST passes467 \item 468 \Indexc{-l}\index{trans lator option!-l@{©-l©}}, \Indexc{--libcfa}\index{translator option!--libcfa@{©--libcfa©}} \, generate ©libcfa.c©469 \item 470 \Indexc{-L}\index{trans lator option!-L@{©-L©}}, \Indexc{--linemarks}\index{translator option!--linemarks@{©--linemarks©}} \, generate line marks471 \item 472 \Indexc{-m}\index{trans lator option!-m@{©-m©}}, \Indexc{--no-main}\index{translator option!--no-main@{©--no-main©}} \, do not replace main473 \item 474 \Indexc{-N}\index{trans lator option!-N@{©-N©}}, \Indexc{--no-linemarks}\index{translator option!--no-linemarks@{©--no-linemarks©}} \, do not generate line marks475 \item 476 \Indexc{-n}\index{trans lator option!-n@{©-n©}}, \Indexc{--no-prelude}\index{translator option!--no-prelude@{©--no-prelude©}} \, do not read prelude477 \item 478 \Indexc{-p}\index{trans lator option!-p@{©-p©}}, \Indexc{--prototypes}\index{translator option!--prototypes@{©--prototypes©}} \, do not generate prelude prototypes $\Rightarrow$ prelude not printed479 \item 480 \Indexc{-d}\index{trans lator option!-d@{©-d©}}, \Indexc{--deterministic-out}\index{translator option!--deterministic-out@{©--deterministic-out©}} \, only print deterministic output481 \item 482 \Indexc{-P}\index{trans lator option!-P@{©-P©}}, \Indexc{--print}\index{translator option!--print@{©--print©}} \, one of:466 \Indexc{-c}\index{transpiler option!-c@{©-c©}}, \Indexc{--colors}\index{transpiler option!--colors@{©--colors©}} \, diagnostic color: ©never©, ©always©, \lstinline[deletekeywords=auto]{auto} 467 \item 468 \Indexc{-g}\index{transpiler option!-g@{©-g©}}, \Indexc{--gdb}\index{transpiler option!--gdb@{©--gdb©}} \, wait for gdb to attach 469 \item 470 \Indexc{-h}\index{transpiler option!-h@{©-h©}}, \Indexc{--help}\index{transpiler option!--help@{©--help©}} \, print transpiler help message 471 \item 472 \Indexc{-i}\index{transpiler option!-i@{©-i©}}, \Indexc{--invariant}\index{transpiler option!--invariant@{©--invariant©}} \, invariant checking during AST passes 473 \item 474 \Indexc{-l}\index{transpiler option!-l@{©-l©}}, \Indexc{--libcfa}\index{transpiler option!--libcfa@{©--libcfa©}} \, generate ©libcfa.c© 475 \item 476 \Indexc{-L}\index{transpiler option!-L@{©-L©}}, \Indexc{--linemarks}\index{transpiler option!--linemarks@{©--linemarks©}} \, generate line marks 477 \item 478 \Indexc{-m}\index{transpiler option!-m@{©-m©}}, \Indexc{--no-main}\index{transpiler option!--no-main@{©--no-main©}} \, do not replace main 479 \item 480 \Indexc{-N}\index{transpiler option!-N@{©-N©}}, \Indexc{--no-linemarks}\index{transpiler option!--no-linemarks@{©--no-linemarks©}} \, do not generate line marks 481 \item 482 \Indexc{-n}\index{transpiler option!-n@{©-n©}}, \Indexc{--no-prelude}\index{transpiler option!--no-prelude@{©--no-prelude©}} \, do not read prelude 483 \item 484 \Indexc{-p}\index{transpiler option!-p@{©-p©}}, \Indexc{--prototypes}\index{transpiler option!--prototypes@{©--prototypes©}} \, do not generate prelude prototypes $\Rightarrow$ prelude not printed 485 \item 486 \Indexc{-d}\index{transpiler option!-d@{©-d©}}, \Indexc{--deterministic-out}\index{transpiler option!--deterministic-out@{©--deterministic-out©}} \, only print deterministic output 487 \item 488 \Indexc{-P}\index{transpiler option!-P@{©-P©}}, \Indexc{--print}\index{transpiler option!--print@{©--print©}} \, one of: 483 489 \begin{description}[topsep=0pt,itemsep=0pt,parsep=0pt] 484 490 \item 485 \Indexc{ascodegen}\index{trans lator option!-P@{©-P©}!©ascodegen©}\index{translator option!--print@{©-print©}!©ascodegen©} \, print AST as codegen rather than AST486 \item 487 \Indexc{asterr}\index{trans lator option!-P@{©-P©}!©asterr©}\index{translator option!--print@{©-print©}!©asterr©} \, print AST on error488 \item 489 \Indexc{declstats}\index{trans lator option!-P@{©-P©}!©declstats©}\index{translator option!--print@{©-print©}!©declstats©} \, print code property statistics490 \item 491 \Indexc{parse}\index{trans lator option!-P@{©-P©}!©parse©}\index{translator option!--print@{©-print©}!©parse©} \, print yacc (parsing) debug information492 \item 493 \Indexc{pretty}\index{trans lator option!-P@{©-P©}!©pretty©}\index{translator option!--print@{©-print©}!©pretty©} \, prettyprint for ©ascodegen© flag494 \item 495 \Indexc{rproto}\index{trans lator option!-P@{©-P©}!©rproto©}\index{translator option!--print@{©-print©}!©rproto©} \, resolver-proto instance496 \item 497 \Indexc{rsteps}\index{trans lator option!-P@{©-P©}!©rsteps©}\index{translator option!--print@{©-print©}!©rsteps©} \, print resolver steps498 \item 499 \Indexc{ast}\index{trans lator option!-P@{©-P©}!©ast©}\index{translator option!--print@{©-print©}!©ast©} \, print AST after parsing500 \item 501 \Indexc{excpdecl}\index{trans lator option!-P@{©-P©}!©excpdecl©}\index{translator option!--print@{©-print©}!©excpdecl©} \, print AST after translating exception decls502 \item 503 \Indexc{symevt}\index{trans lator option!-P@{©-P©}!©symevt©}\index{translator option!--print@{©-print©}!©symevt©} \, print AST after symbol table events504 \item 505 \Indexc{expralt}\index{trans lator option!-P@{©-P©}!©expralt©}\index{translator option!--print@{©-print©}!©expralt©} \, print AST after expressions alternatives506 \item 507 \Indexc{valdecl}\index{trans lator option!-P@{©-P©}!©valdecl©}\index{translator option!--print@{©-print©}!©valdecl©} \, print AST after declaration validation pass508 \item 509 \Indexc{bresolver}\index{trans lator option!-P@{©-P©}!©bresolver©}\index{translator option!--print@{©-print©}!©bresolver©} \, print AST before resolver step510 \item 511 \Indexc{expranly}\index{trans lator option!-P@{©-P©}!©expranly©}\index{translator option!--print@{©-print©}!©expranly©} \, print AST after expression analysis512 \item 513 \Indexc{ctordtor}\index{trans lator option!-P@{©-P©}!©ctordtor©}\index{translator option!--print@{©-print©}!©ctordtor©} \, print AST after ctor/dtor are replaced514 \item 515 \Indexc{tuple}\index{trans lator option!-P@{©-P©}!©tuple©}\index{translator option!--print@{©-print©}!©tuple©} \, print AST after tuple expansion516 \item 517 \Indexc{instgen}\index{trans lator option!-P@{©-P©}!©instgen©}\index{translator option!--print@{©-print©}!©instgen©} \, print AST after instantiate generics518 \item 519 \Indexc{bbox}\index{trans lator option!-P@{©-P©}!©bbox©}\index{translator option!--print@{©-print©}!©bbox©} \, print AST before box pass520 \item 521 \Indexc{bcodegen}\index{trans lator option!-P@{©-P©}!©bcodegen©}\index{translator option!--print@{©-print©}!©bcodegen©} \, print AST before code generation491 \Indexc{ascodegen}\index{transpiler option!-P@{©-P©}!©ascodegen©}\index{transpiler option!--print@{©-print©}!©ascodegen©} \, print AST as codegen rather than AST 492 \item 493 \Indexc{asterr}\index{transpiler option!-P@{©-P©}!©asterr©}\index{transpiler option!--print@{©-print©}!©asterr©} \, print AST on error 494 \item 495 \Indexc{declstats}\index{transpiler option!-P@{©-P©}!©declstats©}\index{transpiler option!--print@{©-print©}!©declstats©} \, print code property statistics 496 \item 497 \Indexc{parse}\index{transpiler option!-P@{©-P©}!©parse©}\index{transpiler option!--print@{©-print©}!©parse©} \, print yacc (parsing) debug information 498 \item 499 \Indexc{pretty}\index{transpiler option!-P@{©-P©}!©pretty©}\index{transpiler option!--print@{©-print©}!©pretty©} \, prettyprint for ©ascodegen© flag 500 \item 501 \Indexc{rproto}\index{transpiler option!-P@{©-P©}!©rproto©}\index{transpiler option!--print@{©-print©}!©rproto©} \, resolver-proto instance 502 \item 503 \Indexc{rsteps}\index{transpiler option!-P@{©-P©}!©rsteps©}\index{transpiler option!--print@{©-print©}!©rsteps©} \, print resolver steps 504 \item 505 \Indexc{ast}\index{transpiler option!-P@{©-P©}!©ast©}\index{transpiler option!--print@{©-print©}!©ast©} \, print AST after parsing 506 \item 507 \Indexc{excpdecl}\index{transpiler option!-P@{©-P©}!©excpdecl©}\index{transpiler option!--print@{©-print©}!©excpdecl©} \, print AST after translating exception decls 508 \item 509 \Indexc{symevt}\index{transpiler option!-P@{©-P©}!©symevt©}\index{transpiler option!--print@{©-print©}!©symevt©} \, print AST after symbol table events 510 \item 511 \Indexc{expralt}\index{transpiler option!-P@{©-P©}!©expralt©}\index{transpiler option!--print@{©-print©}!©expralt©} \, print AST after expressions alternatives 512 \item 513 \Indexc{valdecl}\index{transpiler option!-P@{©-P©}!©valdecl©}\index{transpiler option!--print@{©-print©}!©valdecl©} \, print AST after declaration validation pass 514 \item 515 \Indexc{bresolver}\index{transpiler option!-P@{©-P©}!©bresolver©}\index{transpiler option!--print@{©-print©}!©bresolver©} \, print AST before resolver step 516 \item 517 \Indexc{expranly}\index{transpiler option!-P@{©-P©}!©expranly©}\index{transpiler option!--print@{©-print©}!©expranly©} \, print AST after expression analysis 518 \item 519 \Indexc{ctordtor}\index{transpiler option!-P@{©-P©}!©ctordtor©}\index{transpiler option!--print@{©-print©}!©ctordtor©} \, print AST after ctor/dtor are replaced 520 \item 521 \Indexc{tuple}\index{transpiler option!-P@{©-P©}!©tuple©}\index{transpiler option!--print@{©-print©}!©tuple©} \, print AST after tuple expansion 522 \item 523 \Indexc{instgen}\index{transpiler option!-P@{©-P©}!©instgen©}\index{transpiler option!--print@{©-print©}!©instgen©} \, print AST after instantiate generics 524 \item 525 \Indexc{bbox}\index{transpiler option!-P@{©-P©}!©bbox©}\index{transpiler option!--print@{©-print©}!©bbox©} \, print AST before box pass 526 \item 527 \Indexc{bcodegen}\index{transpiler option!-P@{©-P©}!©bcodegen©}\index{transpiler option!--print@{©-print©}!©bcodegen©} \, print AST before code generation 522 528 \end{description} 523 529 \item 524 530 \Indexc{--prelude-dir} <directory> \, prelude directory for debug/nodebug 525 531 \item 526 \Indexc{-S}\index{trans lator option!-S@{©-S©}!©counters,heap,time,all,none©}, \Indexc{--statistics}\index{translator option!--statistics@{©--statistics©}!©counters,heap,time,all,none©} <option-list> \, enable profiling information: ©counters©, ©heap©, ©time©, ©all©, ©none©527 \item 528 \Indexc{-t}\index{trans lator option!-t@{©-t©}}, \Indexc{--tree}\index{translator option!--tree@{©--tree©}} build in tree532 \Indexc{-S}\index{transpiler option!-S@{©-S©}!©counters,heap,time,all,none©}, \Indexc{--statistics}\index{transpiler option!--statistics@{©--statistics©}!©counters,heap,time,all,none©} <option-list> \, enable profiling information: ©counters©, ©heap©, ©time©, ©all©, ©none© 533 \item 534 \Indexc{-t}\index{transpiler option!-t@{©-t©}}, \Indexc{--tree}\index{transpiler option!--tree@{©--tree©}} build in tree 529 535 \end{description} 530 536 … … 540 546 \end{cfa} 541 547 Existing C programs with keyword clashes can be converted by prefixing the keyword identifiers with double backquotes, and eventually the identifier name can be changed to a non-keyword name. 542 \VRef[Figure]{f:HeaderFileInterposition} shows how clashes in existing C header-files \see{\VRef{s:StandardHeaders}} can be handled using preprocessor \newterm{interposition}: ©#include_next© and ©-I filename©.543 Several common C header-files with keyword clashes are fixed in the standard \CFA header-library, so there is a seamless programming-experience.548 \VRef[Figure]{f:HeaderFileInterposition} shows how clashes in existing C header-files \see{\VRef{s:StandardHeaders}} can be handled using preprocessor \newterm{interposition}: ©#include_next© and command-line ©-I filename©. 549 Several common C header-files with keyword clashes are fixed in the standard \CFA header-library, so there is largely a seamless programming-experience. 544 550 545 551 \begin{figure} … … 591 597 the type suffixes ©U©, ©L©, \etc may start with an underscore ©1_U©, ©1_ll© or ©1.0E10_f©. 592 598 \end{enumerate} 593 It is significantly easier to read and enter long constants when they are broken up into smaller groupings (m anycultures use comma and/or period among digits for the same purpose).599 It is significantly easier to read and enter long constants when they are broken up into smaller groupings (most cultures use comma and/or period among digits for the same purpose). 594 600 This extension is backwards compatible, matches with the use of underscore in variable names, and appears in \Index*{Ada} and \Index*{Java} 8. 595 601 \CC uses the single quote (©'©) as a separator, restricted within a sequence of digits, \eg ©0xaa©©'©©ff©, ©3.141©©'©©592E1©©'©©1©. 602 However, the drawback of the \CC approach is difficults parsing for IDEs between character and numeric constants, as quotes are no longer balanced (©'x'© and ©3.14©©'©©159©). 596 603 597 604 598 605 \section{Exponentiation Operator} 599 606 600 C, \CC, and Java (and other programming languages) have noexponentiation operator\index{exponentiation!operator}\index{operator!exponentiation}, \ie $x^y$, and instead use a routine, like \Indexc{pow(x,y)}, to perform the exponentiation operation.607 C, \CC, and Java (and other programming languages) have \emph{no} exponentiation operator\index{exponentiation!operator}\index{operator!exponentiation}, \ie $x^y$, and instead use a routine, like \Indexc{pow(x,y)}, to perform the exponentiation operation. 601 608 \CFA extends the basic operators with the exponentiation operator ©?©\R{©\\©}©?©\index{?\\?@©?@\@?©} and ©?©\R{©\\©}©=?©\index{?\\=?@©@\@=?©}, as in, ©x ©\R{©\\©}© y© and ©x ©\R{©\\©}©= y©, which means $x^y$ and $x \leftarrow x^y$. 602 609 The priority of the exponentiation operator is between the cast and multiplicative operators, so that ©w * (int)x \ (int)y * z© is parenthesized as ©(w * (((int)x) \ ((int)y))) * z©. 603 610 604 611 There are exponentiation operators for integral and floating types, including the builtin \Index{complex} types. 605 Integral exponentiation\index{exponentiation!unsigned integral} is performed with repeated multiplication ($O(\log y)$ multipliesor shifting if the exponent is 2).612 Integral exponentiation\index{exponentiation!unsigned integral} is performed with repeated multiplication ($O(\log y)$ or shifting if the exponent is 2). 606 613 Overflow for a large exponent or negative exponent returns zero. 607 614 Floating exponentiation\index{exponentiation!floating} is performed using \Index{logarithm}s\index{exponentiation!logarithm}, so the exponent cannot be negative. … … 620 627 T ?®\®?( T ep, unsigned long int y ); 621 628 \end{cfa} 622 A user type ©T© must define multiplication, one (©1©), and ©*©.629 A user type ©T© must define one (©1©), and multiplication (©*©) \see{\VRef{s:Operator}}. 623 630 624 631 … … 631 638 \subsection{\texorpdfstring{\LstKeywordStyle{if} / \LstKeywordStyle{while} Statement}{if / while Statement}} 632 639 633 The \Indexc{if} /\Indexc{while} expression allows declarations, similar to\Indexc{for} declaration expression.\footnote{640 The \Indexc{if} and \Indexc{while} expressions are extended with declarations, similar to the \Indexc{for} declaration expression.\footnote{ 634 641 Declarations in the \Indexc{do}-©while© condition are not useful because they appear after the loop body.} 635 642 \begin{cfa} … … 653 660 \label{s:caseClause} 654 661 655 C restricts a \Indexc{case} clause in\Indexc{switch} statement to a single value.662 C restricts the \Indexc{case} clause in a \Indexc{switch} statement to a single value. 656 663 For multiple ©case© clauses prefixing a statement within the ©switch© statement, it is necessary to have multiple ©case© clauses rather than multiple values. 657 664 Requiring a ©case© clause for each value is not in the spirit of brevity normally associated with C. … … 688 695 \end{tabular} 689 696 \end{cquote} 690 In addition, subranges are allowed to specify case values.697 In addition, subranges are allowed to specify a contiguous set of case values. 691 698 \begin{cquote} 692 699 \begin{tabular}{@{}l@{\hspace{3em}}l@{\hspace{2em}}l@{\hspace{2em}}l@{}} … … 801 808 \end{cfa} 802 809 This situation is better handled by a list of case values \see{\VRef{s:caseClause}}. 803 While fall-through itself is not a problem, the problem occurs when fall-through is the default, as this semantics is unintuitive to many programmers and is different from most programming languages with a ©switch© statement. 804 Hence, default fall-through semantics results in a many programming errors as programmers often \emph{forget} the ©break© statement at the end of a ©case© clause, resulting in inadvertent fall-through. 810 811 While fall-through itself is not a problem, the problem occurs when fall-through is the default, as this semantics is unintuitive for many programmers and is different from most programming languages with a ©switch© statement. 812 Hence, default fall-through semantics results in programming errors as programmers often \emph{forget} the ©break© statement at the end of a ©case© clause, resulting in inadvertent fall-through. 805 813 806 814 \item … … 819 827 The technical problem results from the inability to ensure declaration and initialization of variables when blocks are not entered at the beginning. 820 828 There are few arguments for this kind of control flow, and therefore, there is a strong impetus to eliminate it. 821 822 829 This C idiom is known as ``\Index*{Duff's device}''~\cite{Duff83}, from this example: 823 830 \begin{cfa} … … 996 1003 with the current \Indexc{switch}/\Indexc{choose} statement. 997 1004 1005 1006 \subsection{Loop Control} 1007 1008 Looping a fixed number of times, possibly with a loop index, occurs frequently. 1009 \CFA condenses simply looping to facilitate coding speed and safety~\see{examples in \VRef[Figure]{f:LoopControlExamples}}. 1010 1011 The \Indexc{for}, \Indexc{while}, and \Indexc{do} loop-control are extended to allow an empty conditional, which implies a comparison value of ©1© (true). 1012 \begin{cfa} 1013 while ( ®/* empty */® ) §\C{// while ( true )}§ 1014 for ( ®/* empty */® ) §\C{// for ( ; true; )}§ 1015 do ... while ( ®/* empty */® ) §\C{// do ... while ( true )}§ 1016 \end{cfa} 1017 998 1018 \begin{figure} 999 1019 \begin{tabular}{@{}l@{\hspace{50pt}}|l@{}} … … 1003 1023 while () { sout | "empty"; break; } 1004 1024 do { sout | "empty"; break; } while (); 1005 for () { sout | "empty"; break; } §\C [3in]{sout | nl | nlOff;}§1025 for () { sout | "empty"; break; } §\C{sout | nl | nlOff;}§ 1006 1026 1007 1027 for ( 0 ) { sout | "A"; } sout | "zero"; §\C{sout | nl;}§ … … 1045 1065 for ( i; 5 : j; @ -~ -5 ~ 2 : k; 1.5 ~ @ ) { sout | i | j | k; } §\C{sout | nl;}§ 1046 1066 for ( i; 5 : j; @ -~ -5 ~ 2 : k; 1.5 ~ @ ) { sout | i | j | k; } §\C{sout | nl;}§ 1047 for ( i; 5 : k; 1.5 ~ @ : j; @ -~ -5 ~ 2 ) { sout | i | j | k; } §\C{sout | nl;} \CRT§1067 for ( i; 5 : k; 1.5 ~ @ : j; @ -~ -5 ~ 2 ) { sout | i | j | k; } §\C{sout | nl;}§ 1048 1068 \end{cfa} 1049 1069 & … … 1108 1128 % for ( T i ; 3~9 ) => for ( T i = 3 ; i < 9; i += 1 ) // using 1 1109 1129 1110 1111 \subsection{Loop Control} 1112 1113 Looping a fixed number of times, possibly with a loop index, occurs frequently. 1114 \CFA condenses simply looping to facilitate coding speed and safety~\see{examples in \VRef[Figure]{f:LoopControlExamples}}. 1115 1116 The \Indexc{for}, \Indexc{while}, and \Indexc{do} loop-control allow an empty conditional, which implies a comparison value of ©1© (true). 1117 \begin{cfa} 1118 while ( ®/* empty */® ) §\C{// while ( true )}§ 1119 for ( ®/* empty */® ) §\C{// for ( ; true; )}§ 1120 do ... while ( ®/* empty */® ) §\C{// do ... while ( true )}§ 1121 \end{cfa} 1122 1123 The ©for© control has 4 new loop-control operators that are not overloadable: 1130 The ©for© control is extended with 4 new loop-control operators, which are not overloadable: 1124 1131 \begin{description}[itemsep=0pt,parsep=0pt] 1125 1132 \item … … 1195 1202 Similarly, the high value cannot be elided is an anonymous loop index (©1 ~ @©), as there is no index to stop the loop. 1196 1203 \item 1197 ©:© means lowanother index.1204 ©:© means add another index. 1198 1205 \begin{cfa} 1199 1206 for ( i; 5 ®:® j; 2 ~ 12 ~ 3 ) §\C{// for ( typeof(i) i = 1, j = 2; i < 5 \&\& j < 12; i += 1, j += 3 )}§ … … 1212 1219 \subsection{\texorpdfstring{Labelled \LstKeywordStyle{continue} / \LstKeywordStyle{break} Statement}{Labelled continue / break Statement}} 1213 1220 1214 C \Indexc{continue} and \Indexc{break} statements , for altering control flow,are restricted to one level of nesting for a particular control structure.1221 C \Indexc{continue} and \Indexc{break} statements are restricted to one level of nesting for a particular control structure. 1215 1222 This restriction forces programmers to use \Indexc{goto} to achieve the equivalent control-flow for more than one level of nesting. 1216 1223 To prevent having to switch to the ©goto©, \CFA extends the \Indexc{continue}\index{continue@©continue©!labelled}\index{labelled!continue@©continue©} and \Indexc{break}\index{break@©break©!labelled}\index{labelled!break@©break©} with a target label to support static multi-level exit\index{multi-level exit}\index{static multi-level exit}~\cite{Buhr85}, as in Java. … … 1302 1309 Furthermore, the location of the label at the \emph{beginning} of the target control structure informs the reader (\Index{eye candy}) that complex control-flow is occurring in the body of the control structure. 1303 1310 With ©goto©, the label is at the end of the control structure, which fails to convey this important clue early enough to the reader. 1304 Finally, using an explicit target for the transfer instead of an implicit targetallows new constructs to be added or removed without affecting existing constructs.1311 Finally, using an explicit target for the transfer, instead of an implicit target, allows new constructs to be added or removed without affecting existing constructs. 1305 1312 Otherwise, the implicit targets of the current ©continue© and ©break©, \ie the closest enclosing loop or ©switch©, change as certain constructs are added or removed. 1306 1313 … … 1373 1380 \begin{cfa} 1374 1381 Person p 1375 ®p.®name ; ®p.®address; ®p.®sex;§\C{// access containing fields}§1382 ®p.®name ...; ®p.®address ...; ®p.®sex ...; §\C{// access containing fields}§ 1376 1383 \end{cfa} 1377 1384 which extends to multiple levels of qualification for nested aggregates and multiple aggregates. 1378 1385 \begin{cfa} 1379 1386 struct Ticket { ... } t; 1380 ®p.name®.first ; ®p.address®.street;§\C{// access nested fields}§1381 ®t.®departure ; ®t.®cost;§\C{// access multiple aggregate}§1387 ®p.name®.first ...; ®p.address®.street ...; §\C{// access nested fields}§ 1388 ®t.®departure ...; ®t.®cost ...; §\C{// access multiple aggregate}§ 1382 1389 \end{cfa} 1383 1390 Repeated aggregate qualification is tedious and makes code difficult to read. … … 1558 1565 1559 1566 1560 \s ection{Non-local Exception}1567 \subsection{Non-local Exception} 1561 1568 1562 1569 \begin{cfa} … … 2347 2354 \subsection{Implicit String Conversions} 2348 2355 2349 The types ©char©, ©char *©, ©int©, ©double©, ©_Complex©, including signness and different sizes, implicitly convert to type ©string©. 2350 \VRef[Figure]{f:ImplicitStringConversions} shows examples of implicit conversion between C strings, integral, floating-point and complex types to ©string© 2351 The implicit conversions can be specified explicitly, as in: 2352 \begin{cfa} 2353 s = string( "abc" ); // converts char * to string 2354 s = string( 5 ); // converts int to string 2355 s = string( 5.5 ); // converts double to string 2356 \end{cfa} 2357 Conversions from ©string© to ©char *© are supported but with restrictions. 2358 Explicit As well, when a string is converted to a ©char *©, the storage for the ©char *© is created by the conversion operation, which must be subsequently deleted: 2359 \begin{cfa} 2360 string x = "abc"; 2361 char *p = x; // convert from string to char * 2362 ... 2363 delete p; // free storage created for p 2364 \end{cfa} 2356 The types ©char©, ©char *©, ©int©, ©double©, ©_Complex©, including different signness and sizes, implicitly convert to type ©string©. 2357 \VRef[Figure]{f:ImplicitConversionsString} shows examples of implicit conversions between C strings, integral, floating-point and complex types to ©string©. 2358 A conversions can be explicitly specified: 2359 \begin{cfa} 2360 s = string( "abc" ); §\C{// converts char * to string}§ 2361 s = string( 5 ); §\C{// converts int to string}§ 2362 s = string( 5.5 ); §\C{// converts double to string}§ 2363 \end{cfa} 2364 All conversions from ©string© to ©char *©, attempt to be safe: 2365 either by requiring the maximum length of the ©char *© storage (©strncpy©) or allocating the ©char *© storage for the string characters (ownership), meaning the programmer must free the storage. 2366 As well, a string is always null terminates, implying a minimum size of 1 character. 2367 \begin{cquote} 2368 \begin{tabular}{@{}l@{\hspace{1.75in}}|@{\hspace{15pt}}l@{}} 2369 \begin{cfa} 2370 string s = "abcde"; 2371 char cs[3]; 2372 strncpy( cs, s, sizeof(cs) ); §\C{sout | cs;}§ 2373 char * cp = s; §\C{sout | cp;}§ 2374 delete( cp ); 2375 cp = s + ' ' + s; §\C{sout | cp;}§ 2376 delete( cp ); 2377 \end{cfa} 2378 & 2379 \begin{cfa} 2380 2381 2382 ab 2383 abcde 2384 2385 abcde abcde 2386 2387 \end{cfa} 2388 \end{tabular} 2389 \end{cquote} 2365 2390 2366 2391 \begin{figure} … … 2370 2395 string s; 2371 2396 // conversion of char and char * to string 2372 s = 'x'; §\C D{sout | s;}§2373 s = "abc"; §\C D{sout | s;}§2397 s = 'x'; §\C{sout | s;}§ 2398 s = "abc"; §\C{sout | s;}§ 2374 2399 char cs[5] = "abc"; 2375 s = cs; §\C D{sout | s;}§2400 s = cs; §\C{sout | s;}§ 2376 2401 // conversion of integral, floating-point, and complex to string 2377 s = 45hh; §\CD{sout | s;}§ 2378 s = 45h; §\CD{sout | s;}§ 2379 s = -(ssize_t)MAX - 1; §\CD{sout | s;}§ 2380 s = (size_t)MAX; §\CD{sout | s;}§ 2381 s = 5.5; §\CD{sout | s;}§ 2382 s = 5.5L; §\CD{sout | s;}§ 2383 s = 5.5+3.4i; §\CD{sout | s;}§ 2384 s = 5.5L+3.4Li; §\CD{sout | s;}§ 2385 // safe conversion from string to char * 2386 strncpy( cs, s, sizeof(cs) ); §\CD{sout | cs;}§ 2387 char * cp = s; §\CD{sout | cp; // ownership}§ 2388 delete( cp ); 2389 cp = s + ' ' + s; §\CD{sout | cp; // ownership}§ 2390 delete( cp ); 2402 s = 45hh; §\C{sout | s;}§ 2403 s = 45h; §\C{sout | s;}§ 2404 s = -(ssize_t)MAX - 1; §\C{sout | s;}§ 2405 s = (size_t)MAX; §\C{sout | s;}§ 2406 s = 5.5; §\C{sout | s;}§ 2407 s = 5.5L; §\C{sout | s;}§ 2408 s = 5.5+3.4i; §\C{sout | s;}§ 2409 s = 5.5L+3.4Li; §\C{sout | s;}§ 2391 2410 \end{cfa} 2392 2411 & … … 2408 2427 5.5+3.4i 2409 2428 5.5+3.4i 2410 2411 5.5+2412 5.5+3.4i2413 2414 5.5+3.4i 5.5+3.4i2415 2416 2429 \end{cfa} 2417 2430 \end{tabular} 2418 \caption{Implicit String Conversions}2419 \label{f:Implicit StringConversions}2431 \caption{Implicit Conversions to String} 2432 \label{f:ImplicitConversionsString} 2420 2433 \end{figure} 2421 2434 2422 2435 2436 \subsection{Size (length)} 2437 2438 The ©size© operation returns the length of a string. 2439 \begin{cfa} 2440 i = size( "" ); §\C{// i is assigned 0}§ 2441 i = size( "abc" ); §\C{// i is assigned 3}§ 2442 i = size( peter ); §\C{// i is assigned 5}§ 2443 \end{cfa} 2444 2445 2423 2446 \subsection{Comparison Operators} 2424 2447 2425 The binary relational and equality operators ©<©, ©<=©, ©>©, ©>=©, ©==©, ©!=© compare ©string©using lexicographical ordering, where longer strings are greater than shorter strings.2448 The binary \Index{relational operator}s, ©<©, ©<=©, ©>©, ©>=©, and \Index{equality operator}s, ©==©, ©!=©, compare strings using lexicographical ordering, where longer strings are greater than shorter strings. 2426 2449 2427 2450 2428 2451 \subsection{Concatenation} 2429 2452 2430 The binary operator ©+© concatenates two strings. 2431 \begin{cfa} 2432 s = peter + digit; §\C{// s is assigned "PETER0123456789"}§ 2433 s += peter; §\C{// s is assigned "PETER0123456789PETER"}§ 2434 \end{cfa} 2435 There is also an assignment form ©+=©. 2453 The binary operators \Indexc{+} and \Indexc{+=} concatenate two strings, creating the sum of the strings. 2454 \begin{cfa} 2455 s = peter + ' ' + digit; §\C{// s is assigned "PETER 0123456789"}§ 2456 s += peter; §\C{// s is assigned "PETER 0123456789PETER"}§ 2457 \end{cfa} 2436 2458 2437 2459 2438 2460 \subsection{Repetition} 2439 2461 2440 The binary operator \Indexc{*} returns a string that is the string repeated ©n© times. 2441 If ©n = 0©, a zero length string, ©""© is returned. 2442 \begin{cfa} 2443 s = (peter + ' ') * 3; §\C{// s is assigned "PETER PETER PETER"}§ 2444 \end{cfa} 2445 There is also an assignment form ©*=©. 2446 2447 2448 \subsection{Length} 2449 2450 The ©length© operation 2451 \begin{cfa} 2452 int length() 2453 \end{cfa} 2454 returns the length of a string variable. 2455 \begin{cfa} 2456 i = peter.length(); §\C{// i is assigned the value 5}§ 2462 The binary operators \Indexc{*} and \Indexc{*=} repeat a string $N$ times. 2463 If $N = 0$, a zero length string, ©""© is returned. 2464 \begin{cfa} 2465 s = 'x' * 3; §\C{// s is assigned "PETER PETER PETER "}§ 2466 s = (peter + ' ') * 3; §\C{// s is assigned "PETER PETER PETER "}§ 2457 2467 \end{cfa} 2458 2468 2459 2469 2460 2470 \subsection{Substring} 2461 The substring operation: 2462 \begin{cfa} 2463 string operator () (int start, int lnth); 2464 \end{cfa} 2465 performs a substring operation that returns the string starting at a specified position (©start©) in the current string, and having the specified length (©lnth©). 2471 The substring operation returns a subset of the string starting at a position in the string and traversing a length. 2472 \begin{cfa} 2473 s = peter( 2, 3 ); §\C{// s is assigned "ETE"}§ 2474 s = peter( 4, -3 ); §\C{// s is assigned "ETE", length is opposite direction}§ 2475 s = peter( 2, 8 ); §\C{// s is assigned "ETER", length is clipped to 4}§ 2476 s = peter( 0, -1 ); §\C{// s is assigned "", beyond string so clipped to null}§ 2477 s = peter(-1, -1 ); §\C{// s is assigned "R", start and length are negative}§ 2478 \end{cfa} 2466 2479 A negative starting position is a specification from the right end of the string. 2467 2480 A negative length means that characters are selected in the opposite (right to left) direction from the starting position. 2468 2481 If the substring request extends beyond the beginning or end of the string, it is clipped (shortened) to the bounds of the string. 2469 2482 If the substring request is completely outside of the original string, a null string located at the end of the original string is returned. 2470 \begin{cfa}2471 s = peter( 2, 3 ); §\C{// s is assigned "ETE"}§2472 s = peter( 4, -3 ); §\C{// s is assigned "ETE", length is opposite direction}§2473 s = peter( 2, 8 ); §\C{// s is assigned "ETER", length is clipped to 4}§2474 s = peter( 0, -1 ); §\C{// s is assigned "", beyond string so clipped to null}§2475 s = peter(-1, -1 ); §\C{// s is assigned "R", start and length are negative}§2476 \end{cfa}2477 2483 The substring operation can also appear on the left hand side of the assignment operator. 2478 2484 The substring is replaced by the value on the right hand side of the assignment. 2479 2485 The length of the right-hand-side value may be shorter, the same length, or longer than the length of the substring that is selected on the left hand side of the assignment. 2480 \begin{cfa} [mathescape=false]2481 digit( 3, 3 ) = ""; §\C{// digit is assigned "0156789"}§2482 digit( 4, 3 ) = "xyz"; §\C{// digit is assigned "015xyz9"}§2483 digit( 7, 0 ) = "***"; §\C{// digit is assigned "015xyz***9"}§2484 digit(-4, 3 ) = "$$$"; §\C{// digit is assigned "015xyz\$\$\$9"}§2486 \begin{cfa} 2487 digit( 3, 3 ) = ""; §\C{// digit is assigned "0156789"}§ 2488 digit( 4, 3 ) = "xyz"; §\C{// digit is assigned "015xyz9"}§ 2489 digit( 7, 0 ) = "***"; §\C{// digit is assigned "015xyz***9"}§ 2490 digit(-4, 3 ) = "$$$"; §\C{// digit is assigned "015xyz\$\$\$9"}§ 2485 2491 \end{cfa} 2486 2492 A substring is treated as a pointer into the base (substringed) string rather than creating a copy of the subtext. … … 2501 2507 // e is a substring result passed by value 2502 2508 void test(string &x, string &a, string &b, string &c, string &d, string e) { 2503 §\C{// x a b c d e}§2504 a( 1, 2 ) = "aaa"; §\C{// aaaxxxxxxxxxxx aaax axx xxxxx xxxxx xxxxx}§2505 b( 2, 12 ) = "bbb"; §\C{// aaabbbxxxxxxxxx aaab abbb bbxxx xxxxx xxxxx}§2506 c( 4, 5 ) = "ccc"; §\C{// aaabbbxcccxxxxxx aaab abbb bbxccc ccxxx xxxxx}§2507 c = "yyy"; §\C{// aaabyyyxxxxxx aaab abyy yyy xxxxx xxxxx}§2508 d( 1, 3 ) = "ddd"; §\C{// aaabyyyxdddxx aaab abyy yyy dddxx xxxxx}§2509 e( 1, 3 ) = "eee"; §\C{// aaabyyyxdddxx aaab abyy yyy dddxx eeexx}§2510 x = e; §\C{// eeexx eeex exx x eeexx}§2509 §\C{// x a b c d e}§ 2510 a( 1, 2 ) = "aaa"; §\C{// aaaxxxxxxxxxxx aaax axx xxxxx xxxxx xxxxx}§ 2511 b( 2, 12 ) = "bbb"; §\C{// aaabbbxxxxxxxxx aaab abbb bbxxx xxxxx xxxxx}§ 2512 c( 4, 5 ) = "ccc"; §\C{// aaabbbxcccxxxxxx aaab abbb bbxccc ccxxx xxxxx}§ 2513 c = "yyy"; §\C{// aaabyyyxxxxxx aaab abyy yyy xxxxx xxxxx}§ 2514 d( 1, 3 ) = "ddd"; §\C{// aaabyyyxdddxx aaab abyy yyy dddxx xxxxx}§ 2515 e( 1, 3 ) = "eee"; §\C{// aaabyyyxdddxx aaab abyy yyy dddxx eeexx}§ 2516 x = e; §\C{// eeexx eeex exx x eeexx}§ 2511 2517 } 2512 2518 \end{cfa} … … 2518 2524 For example: 2519 2525 \begin{cfa} 2520 s = peter( 2 ); §\C{// s is assigned "ETER"}§2521 peter( 2 ) = "IPER"; §\C{// peter is assigned "PIPER"}§2526 s = peter( 2 ); §\C{// s is assigned "ETER"}§ 2527 peter( 2 ) = "IPER"; §\C{// peter is assigned "PIPER"}§ 2522 2528 \end{cfa} 2523 2529 It is also possible to substring using a string as the index for selecting the substring portion of the string. … … 2527 2533 For example: 2528 2534 \begin{cfa}[mathescape=false] 2529 digit( "xyz$$$" ) = "678"; §\C{// digit is assigned "0156789"}§ 2530 digit( "234") = "***"; §\C{// digit is assigned "0156789***"}§ 2531 \end{cfa} 2532 %$ 2535 digit( "xyz$$$" ) = "678"; §\C{// digit is assigned "0156789"}§ 2536 digit( "234") = "***"; §\C{// digit is assigned "0156789***"}§ 2537 \end{cfa} 2533 2538 2534 2539 … … 2570 2575 A negative starting position is a specification from the right end of the string. 2571 2576 \begin{cfa} 2572 i = peter.include( digitmask ); §\C{// i is assigned 1}§2573 i = peter.include( alphamask ); §\C{// i is assigned 6}§2577 i = peter.include( digitmask ); §\C{// i is assigned 1}§ 2578 i = peter.include( alphamask ); §\C{// i is assigned 6}§ 2574 2579 \end{cfa} 2575 2580 … … 2622 2627 \begin{cfa} 2623 2628 // remove leading blanks 2624 s = string( " ABC" ).trim( " " ); 2629 s = string( " ABC" ).trim( " " ); §\C{// s is assigned "ABC",}§ 2625 2630 // remove trailing blanks 2626 s = string( "ABC " ).trim( " ", last ); 2631 s = string( "ABC " ).trim( " ", last ); §\C{// s is assigned "ABC",}§ 2627 2632 \end{cfa} 2628 2633 … … 2651 2656 returns a string in which all occurrences of the ©from© string in the current string have been replaced by the ©to© string. 2652 2657 \begin{cfa} 2653 s = peter.replace( "E", "XX" ); §\C{// s is assigned "PXXTXXR"}§2658 s = peter.replace( "E", "XX" ); §\C{// s is assigned "PXXTXXR"}§ 2654 2659 \end{cfa} 2655 2660 The replacement is done left-to-right. 2656 2661 When an instance of the ©from© string is found and changed to the ©to© string, it is NOT examined again for further replacement. 2657 2662 2658 2659 \section{Returning N+1 on Failure} 2663 \subsection{Returning N+1 on Failure} 2660 2664 2661 2665 Any of the string search routines can fail at some point during the search. … … 2687 2691 2688 2692 2693 \subsection{C Compatibility} 2694 2695 To ease conversion from C to \CFA, there are companion ©string© routines for C strings. 2696 \VRef[Table]{t:CompanionStringRoutines} shows the C routines on the left that also work with ©string© and the rough equivalent ©string© opeation of the right. 2697 Hence, it is possible to directly convert a block of C string operations into @string@ just by changing the 2698 2699 \begin{table} 2700 \begin{cquote} 2701 \begin{tabular}{@{}l|l@{}} 2702 \multicolumn{1}{c|}{©char []©} & \multicolumn{1}{c}{©string©} \\ 2703 \hline 2704 ©strcpy©, ©strncpy© & ©=© \\ 2705 ©strcat©, ©strncat© & ©+© \\ 2706 ©strcmp©, ©strncmp© & ©==©, ©!=©, ©<©, ©<=©, ©>©, ©>=© \\ 2707 ©strlen© & ©size© \\ 2708 ©[]© & ©[]© \\ 2709 ©strstr© & ©find© \\ 2710 ©strcspn© & ©find_first_of©, ©find_last_of© \\ 2711 ©strspc© & ©find_fist_not_of©, ©find_last_not_of© 2712 \end{tabular} 2713 \end{cquote} 2714 \caption{Companion Routines for \CFA \lstinline{string} to C Strings} 2715 \label{t:CompanionStringRoutines} 2716 \end{table} 2717 2718 For example, this block of C code can be converted to \CFA by simply changing the type of variable ©s© from ©char []© to ©string©. 2719 \begin{cfa} 2720 char s[32]; 2721 //string s; 2722 strcpy( s, "abc" ); PRINT( %s, s ); 2723 strncpy( s, "abcdef", 3 ); PRINT( %s, s ); 2724 strcat( s, "xyz" ); PRINT( %s, s ); 2725 strncat( s, "uvwxyz", 3 ); PRINT( %s, s ); 2726 PRINT( %zd, strlen( s ) ); 2727 PRINT( %c, s[3] ); 2728 PRINT( %s, strstr( s, "yzu" ) ) ; 2729 PRINT( %s, strstr( s, 'y' ) ) ; 2730 \end{cfa} 2731 However, the conversion fails with I/O because ©printf© cannot print a ©string© using format code ©%s© because \CFA strings are not null terminated. 2732 2733 2689 2734 \subsection{Input/Output Operators} 2690 2735 … … 2707 2752 Hence, enums may be overloaded with variable, enum, and function names. 2708 2753 \begin{cfa} 2709 int Foo; §\C{// type/variable separate namespaces}§2754 int Foo; §\C{// type/variable separate namespaces}§ 2710 2755 enum Foo { Bar }; 2711 enum Goo { Bar }; §\C[1.75in]{// overload Foo.Bar}§2712 double Bar; §\C{// overload Foo.Bar, Goo.Bar}\CRT§2756 enum Goo { Bar }; §\C{// overload Foo.Bar}§ 2757 double Bar; §\C{// overload Foo.Bar, Goo.Bar}§ 2713 2758 \end{cfa} 2714 2759 An anonymous enumeration injects enums with specific values into a scope. … … 2783 2828 The following examples illustrate the difference between the enumeration type and the type of its enums. 2784 2829 \begin{cfa} 2785 Math m = PI; §\C[1.5in]{// allowed}§2786 double d = PI; §\C{// allowed, conversion to base type}§2787 m = E; §\C{// allowed}§2788 m = Alph; §\C{// {\color{red}disallowed}}§2789 m = 3.141597; §\C{// {\color{red}disallowed}}§2790 d = m; §\C{// allowed}§2791 d = Alph; §\C{// {\color{red}disallowed}}§2792 Letter l = A; §\C{// allowed}§2793 Greek g = Alph; §\C{// allowed}§2794 l = Alph; §\C{// allowed, conversion to base type}§2795 g = A; §\C{// {\color{red}disallowed}}\CRT§2830 Math m = PI; §\C{// allowed}§ 2831 double d = PI; §\C{// allowed, conversion to base type}§ 2832 m = E; §\C{// allowed}§ 2833 m = Alph; §\C{// {\color{red}disallowed}}§ 2834 m = 3.141597; §\C{// {\color{red}disallowed}}§ 2835 d = m; §\C{// allowed}§ 2836 d = Alph; §\C{// {\color{red}disallowed}}§ 2837 Letter l = A; §\C{// allowed}§ 2838 Greek g = Alph; §\C{// allowed}§ 2839 l = Alph; §\C{// allowed, conversion to base type}§ 2840 g = A; §\C{// {\color{red}disallowed}}§ 2796 2841 \end{cfa} 2797 2842 … … 3362 3407 For example, consider C's \Indexc{div} function, which returns the quotient and remainder for a division of an integer value. 3363 3408 \begin{cfa} 3364 typedef struct { int quot, rem; } div_t; §\C[7cm]{// from include stdlib.h}§3409 typedef struct { int quot, rem; } div_t; §\C{// from include stdlib.h}§ 3365 3410 div_t div( int num, int den ); 3366 div_t qr = div( 13, 5 ); 3411 div_t qr = div( 13, 5 ); §\C{// return quotient/remainder aggregate}§ 3367 3412 printf( "%d %d\n", qr.quot, qr.rem ); §\C{// print quotient/remainder}§ 3368 3413 \end{cfa} … … 3375 3420 For example, consider C's \Indexc{modf} function, which returns the integral and fractional part of a floating value. 3376 3421 \begin{cfa} 3377 double modf( double x, double * i ); 3422 double modf( double x, double * i ); §\C{// from include math.h}§ 3378 3423 double intp, frac = modf( 13.5, &intp ); §\C{// return integral and fractional components}§ 3379 3424 printf( "%g %g\n", intp, frac ); §\C{// print integral/fractional components}§ … … 3404 3449 When a function call is passed as an argument to another call, the best match of actual arguments to formal parameters is evaluated given all possible expression interpretations in the current scope. 3405 3450 \begin{cfa} 3406 void g( int, int ); 3407 void g( double, double ); 3408 g( div( 13, 5 ) ); 3409 g( modf( 13.5 ) ); 3451 void g( int, int ); §\C{// 1}§ 3452 void g( double, double ); §\C{// 2}§ 3453 g( div( 13, 5 ) ); §\C{// select 1}§ 3454 g( modf( 13.5 ) ); §\C{// select 2}§ 3410 3455 \end{cfa} 3411 3456 In this case, there are two overloaded ©g© routines. … … 3416 3461 The previous examples can be rewritten passing the multiple returned-values directly to the ©printf© function call. 3417 3462 \begin{cfa} 3418 [ int, int ] div( int x, int y ); 3463 [ int, int ] div( int x, int y ); §\C{// from include stdlib}§ 3419 3464 printf( "%d %d\n", div( 13, 5 ) ); §\C{// print quotient/remainder}§ 3420 3465 3421 [ double, double ] modf( double x ); 3466 [ double, double ] modf( double x ); §\C{// from include math}§ 3422 3467 printf( "%g %g\n", modf( 13.5 ) ); §\C{// print integral/fractional components}§ 3423 3468 \end{cfa} … … 3430 3475 \begin{cfa} 3431 3476 int quot, rem; 3432 [ quot, rem ] = div( 13, 5 ); 3433 printf( "%d %d\n", quot, rem ); §\C{// print quotient/remainder}\CRT§3477 [ quot, rem ] = div( 13, 5 ); §\C{// assign multiple variables}§ 3478 printf( "%d %d\n", quot, rem ); §\C{// print quotient/remainder}§ 3434 3479 \end{cfa} 3435 3480 Here, the multiple return-values are matched in much the same way as passing multiple return-values to multiple parameters in a call. … … 3848 3893 The general syntax of a lexical list is: 3849 3894 \begin{cfa} 3850 [ $\emph{exprlist}$]3851 \end{cfa} 3852 where ©$\emph{exprlist}$©is a list of one or more expressions separated by commas.3895 [ §\emph{exprlist}§ ] 3896 \end{cfa} 3897 where \LstBasicStyle{\emph{exprlist}} is a list of one or more expressions separated by commas. 3853 3898 The brackets, ©[]©, allow differentiating between lexical lists and expressions containing the C comma operator. 3854 3899 The following are examples of lexical lists: … … 3856 3901 [ x, y, z ] 3857 3902 [ 2 ] 3858 [ v +w, x*y, 3.14159, f() ]3903 [ v + w, x * y, 3.14159, f() ] 3859 3904 \end{cfa} 3860 3905 Tuples are permitted to contain sub-tuples (\ie nesting), such as ©[ [ 14, 21 ], 9 ]©, which is a 2-element tuple whose first element is itself a tuple. … … 3868 3913 The general syntax of a tuple type is: 3869 3914 \begin{cfa} 3870 [ $\emph{typelist}$]3871 \end{cfa} 3872 where ©$\emph{typelist}$©is a list of one or more legal \CFA or C type specifications separated by commas, which may include other tuple type specifications.3915 [ §\emph{typelist}§ ] 3916 \end{cfa} 3917 where \LstBasicStyle{\emph{typelist}} is a list of one or more legal \CFA or C type specifications separated by commas, which may include other tuple type specifications. 3873 3918 Examples of tuple types include: 3874 3919 \begin{cfa} 3875 3920 [ unsigned int, char ] 3876 3921 [ double, double, double ] 3877 [ * int, int * ] 3922 [ * int, int * ] §\C{// mix of CFA and ANSI}§ 3878 3923 [ * [ 5 ] int, * * char, * [ [ int, int ] ] (int, int) ] 3879 3924 \end{cfa} … … 3882 3927 Examples of declarations using tuple types are: 3883 3928 \begin{cfa} 3884 [ int, int ] x; 3885 * [ char, char ] y; 3929 [ int, int ] x; §\C{// 2 element tuple, each element of type int}§ 3930 * [ char, char ] y; §\C{// pointer to a 2 element tuple}§ 3886 3931 [ [ int, int ] ] z ([ int, int ]); 3887 3932 \end{cfa} … … 3900 3945 [ int, int ] w1; 3901 3946 [ int, int, int ] w2; 3902 [ void ] f (int, int, int); 3903 [ void ] g ([ int, int, int ]); §\C{3 element tuple as input}§3947 [ void ] f (int, int, int); §\C{// three input parameters of type int}§ 3948 [ void ] g ([ int, int, int ]); §\C{// 3 element tuple as input}§ 3904 3949 f( [ 1, 2, 3 ] ); 3905 3950 f( w1, 3 ); … … 3982 4027 [ int, int, int, int ] w = [ 1, 2, 3, 4 ]; 3983 4028 int x = 5; 3984 [ x, w ] = [ w, x ]; 4029 [ x, w ] = [ w, x ]; §\C{// all four tuple coercions}§ 3985 4030 \end{cfa} 3986 4031 Starting on the right-hand tuple in the last assignment statement, w is opened, producing a tuple of four values; … … 4000 4045 Mass assignment has the following form: 4001 4046 \begin{cfa} 4002 [ $\emph{lvalue}$, ... , $\emph{lvalue}$ ] = $\emph{expr}$;4047 [ §\emph{lvalue}§, ... , §\emph{lvalue}§ ] = §\emph{expr}§; 4003 4048 \end{cfa} 4004 4049 \index{lvalue} 4005 The left-hand side is a tuple of \ emph{lvalues}, which is a list of expressions each yielding an address, \ie any data object that can appear on the left-hand side of a conventional assignment statement.4006 ©$\emph{expr}$©is any standard arithmetic expression.4050 The left-hand side is a tuple of \LstBasicStyle{\emph{lvalues}}, which is a list of expressions each yielding an address, \ie any data object that can appear on the left-hand side of a conventional assignment statement. 4051 \LstBasicStyle{\emph{expr}} is any standard arithmetic expression. 4007 4052 Clearly, the types of the entities being assigned must be type compatible with the value of the expression. 4008 4053 … … 4041 4086 Multiple assignment has the following form: 4042 4087 \begin{cfa} 4043 [ $\emph{lvalue}$, ... , $\emph{lvalue}$ ] = [ $\emph{expr}$, ... , $\emph{expr}$];4088 [ §\emph{lvalue}§, ... , §\emph{lvalue}§ ] = [ §\emph{expr}§, ... , §\emph{expr}§ ]; 4044 4089 \end{cfa} 4045 4090 \index{lvalue} … … 4072 4117 both these examples produce indeterminate results: 4073 4118 \begin{cfa} 4074 f( x++, x++ ); 4075 [ v1, v2 ] = [ x++, x++ ]; 4119 f( x++, x++ ); §\C{// C routine call with side effects in arguments}§ 4120 [ v1, v2 ] = [ x++, x++ ]; §\C{// side effects in right-hand side of multiple assignment}§ 4076 4121 \end{cfa} 4077 4122 … … 4083 4128 Cascade assignment has the following form: 4084 4129 \begin{cfa} 4085 $\emph{tuple}$ = $\emph{tuple}$ = ... = $\emph{tuple}$;4130 §\emph{tuple}§ = §\emph{tuple}§ = ... = §\emph{tuple}§; 4086 4131 \end{cfa} 4087 4132 and it has the same parallel semantics as for mass and multiple assignment. … … 4103 4148 The goal of \CFA stream input/output (I/O) is to simplify the common cases\index{I/O!common case}, while fully supporting polymorphism and user defined types in a consistent way. 4104 4149 Stream I/O can be implicitly or explicitly formatted. 4105 Implicit formatting means \CFA selects the output or input format for values that matches the variable's type. 4106 Explicit formatting means additional information is specified to augment how an output or input of value is interpreted. 4150 Implicit formatting means \CFA selects an I/O format for values that matches a variable's type. 4151 Explicit formatting means additional I/O information is specified to control how a value is interpreted. 4152 4107 4153 \CFA formatting incorporates ideas from C ©printf©, \CC ©stream© manipulators, and Python implicit spacing and newline. 4108 4154 Specifically: … … 4112 4158 \CFA/\CC format manipulators are named, making them easier to read and remember. 4113 4159 \item 4114 ©printf©/Python separate sformat codes from associated variables, making it difficult to match codes with variables.4160 ©printf©/Python separate format codes from associated variables, making it difficult to match codes with variables. 4115 4161 \CFA/\CC co-locate codes with associated variables, where \CFA has the tighter binding. 4116 4162 \item 4117 Format manipulators in \CFA have local effect, whereas \CC have global effect, except ©setw©.4118 Hence, it is common programming practice to toggle manipulators on and then back to the default to prevent downstream side-effects.4163 Format manipulators in ©printf©/Python/\CFA have local effect, whereas \CC have global effect, except ©setw©. 4164 Hence, it is common \CC programming practice to toggle manipulators on and then back to the default to prevent downstream side-effects. 4119 4165 Without this programming style, errors occur when moving prints, as manipulator effects incorrectly flow into the new location. 4120 4166 Furthermore, to guarantee no side-effects, manipulator values must be saved and restored across function calls. 4167 \CC programers never do any of this. 4121 4168 \item 4122 4169 \CFA has more sophisticated implicit value spacing than Python, plus implicit newline at the end of a print. 4123 4170 \end{itemize} 4124 4171 4125 The standard polymorphic I/Os stream are ©stdin©/©sin© (input), ©stdout©/©sout© and ©stderr©/©serr© (output) (like C++ ©cin©/©cout©/©cerr©). 4126 Polymorphic streams ©exit© and ©abort© provide implicit program termination without and with generating a stack trace and core file. 4127 Stream ©exit© implicitly returns ©EXIT_FAILURE© to the shell. 4128 \begin{cfa} 4129 ®exit® | "x (" | x | ") negative value."; // terminate and return EXIT_FAILURE to shell 4130 ®abort® | "x (" | x | ") negative value."; // terminate and generate stack trace and core file 4131 \end{cfa} 4132 Note, \CFA stream variables ©stdin©, ©stdout©, ©stderr©, ©exit©, and ©abort© overload C variables ©stdin©, ©stdout©, ©stderr©, and functions ©exit© and ©abort©, respectively. 4172 4173 \subsection{Basic I/O} 4174 4175 The standard polymorphic I/O streams are ©stdin©/©sin© (input), ©stdout©/©sout©, and ©stderr©/©serr© (output) (like C++ ©cin©/©cout©/©cerr©). 4176 The standard I/O operator is the bit-wise (or) operator, ©'|'©, which is used to cascade multiple I/O operations. 4133 4177 The \CFA header file for the I/O library is \Indexc{fstream.hfa}. 4134 4135 4136 \subsection{Basic I/O}4137 4178 4138 4179 For implicit formatted output, the common case is printing a series of variables separated by whitespace. … … 4177 4218 1®, ®2®, ®3 4®, ®5®, ®6 4178 4219 \end{cfa} 4179 Finally, \CFA uses the logical-or operator for I/O as it is the lowest-priority \emph{overloadable} operator, other than assignment. 4220 The bit-wise ©|© operator is used for I/O, rather \CC shift-operators, ©<<© and ©>>©, as it is the lowest-priority \emph{overloadable} operator, other than assignment. 4221 (Operators ©||© and ©&&© are not overloadable in \CFA.) 4180 4222 Therefore, fewer output expressions require parenthesis. 4181 4223 \begin{cquote} … … 4200 4242 \end{cquote} 4201 4243 There is a weak similarity between the \CFA logical-or operator and the \Index{Shell pipe-operator} for moving data, where data flows in the correct direction for input but the opposite direction for output. 4202 Input and output use a uniform operator, ©|©, rather than \CC's ©<<© and ©>>© input/output operators , which preventsthis common error in \CC:4244 Input and output use a uniform operator, ©|©, rather than \CC's ©<<© and ©>>© input/output operators to prevent this common error in \CC: 4203 4245 \begin{C++} 4204 4246 cin << i; // why is this generating a lot of error messages? 4205 4247 \end{C++} 4248 4249 Streams ©exit© and ©abort© provide output with immediate program termination without and with generating a stack trace and core file. 4250 Stream ©exit© implicitly returns ©EXIT_FAILURE© to the shell. 4251 \begin{cfa} 4252 ®exit® | "x (" | x | ") negative value."; §\C{// print, terminate, and return EXIT\_FAILURE to shell}§ 4253 ®abort® | "x (" | x | ") negative value."; §\C{// print, terminate, and generate stack trace and core file}§ 4254 \end{cfa} 4255 Note, \CFA stream variables ©stdin©, ©stdout©, ©stderr©, ©exit©, and ©abort© overload C variables ©stdin©, ©stdout©, ©stderr©, and functions ©exit© and ©abort©, respectively. 4206 4256 4207 4257 For implicit formatted input, the common case is reading a sequence of values separated by whitespace, where the type of an input constant must match with the type of the input variable. … … 4246 4296 \end{tabular} 4247 4297 \end{cquote} 4248 4249 \VRef[Figure]{f:CFACommand-LineProcessing} shows idiomatic \CFA command-line processing and copying an input file to an output file. 4298 The format of numeric input values in the same as C constants without a trailing type suffix, as the input value-type is denoted by the input variable. 4299 For ©bool© type, the constants are ©true© and ©false©. 4300 For integral types, any number of digits, optionally preceded by a sign (©+© or ©-©), where a 4301 \begin{itemize} 4302 \item 4303 ©1©-©9© prefix introduces a decimal value (©0©-©9©), 4304 \item 4305 ©0© prefix introduces an octal value (©0©-©7©), and 4306 \item 4307 ©0x© or ©0X© prefix introduces a hexadecimal value (©0©-©f©) with lower or upper case letters. 4308 \end{itemize} 4309 For floating-point types, any number of decimal digits, optionally preceded by a sign (©+© or ©-©), optionally containing a decimal point, and optionally followed by an exponent, ©e© or ©E©, with signed (optional) decimal digits. 4310 Floating-point values can also be written in hexadecimal format preceded by ©0x© or ©0X© with hexadecimal digits and exponent denoted by ©p© or ©P©. 4311 In all cases, all whitespace characters are skipped until an appropriate value is found. 4312 \Textbf{If an appropriate value is not found, the exception ©missing_data© is raised.} 4313 4314 For the C-string type, there are two input forms: any number of \Textbf{non-whitespace} characters or a quoted sequence containing any characters except the closing quote, \ie there is no escape character supported in the string.. 4315 In both cases, the string is null terminated ©'\0'©. 4316 For the quoted string, the start and end quote characters can be any character and do not have to match \see{\ref{XXX}}. 4317 4318 \VRef[Figure]{f:IOStreamFunctions} shows the I/O stream operations for interacting with files other than ©cin©, ©cout©, and ©cerr©. 4319 \begin{itemize}[topsep=4pt,itemsep=2pt,parsep=0pt] 4320 \item 4321 \Indexc{fail} tests the stream error-indicator, returning nonzero if it is set. 4322 \item 4323 \Indexc{clear} resets the stream error-indicator. 4324 \item 4325 \Indexc{flush} (©ofstream© only) causes any unwritten data for a stream to be written to the file. 4326 \item 4327 \Indexc{eof} (©ifstream© only) tests the end-of-file indicator for the stream pointed to by stream. 4328 Returns true if the end-of-file indicator is set, otherwise false. 4329 \item 4330 \Indexc{open} binds the file with ©name© to a stream accessed with ©mode© (see ©fopen©). 4331 \item 4332 \Indexc{close} flushes the stream and closes the file. 4333 \item 4334 \Indexc{write} (©ofstream© only) writes ©size© bytes to the stream. 4335 The bytes are written lazily when an internal buffer fills. 4336 Eager buffer writes are done with ©flush© 4337 \item 4338 \Indexc{read} (©ifstream© only) reads ©size© bytes from the stream. 4339 \item 4340 \Indexc{ungetc} (©ifstream© only) pushes the character back to the input stream. 4341 Pushed-back characters returned by subsequent reads in the reverse order of pushing. 4342 \end{itemize} 4343 The constructor functions: 4344 \begin{itemize}[topsep=4pt,itemsep=2pt,parsep=0pt] 4345 \item 4346 create an unbound stream, which is subsequently bound to a file with ©open©. 4347 \item 4348 create a bound stream to the associated file with given ©mode©. 4349 \end{itemize} 4350 The destructor closes the stream. 4351 4352 \begin{figure} 4353 \begin{cfa} 4354 // *********************************** ofstream *********************************** 4355 bool fail( ofstream & );§\indexc{fail}\index{ofstream@©ofstream©!©fail©}§ 4356 void clear( ofstream & );§\indexc{clear}\index{ofstream@©ofstream©!©clear©}§ 4357 int flush( ofstream & );§\indexc{flush}\index{ofstream@©ofstream©!©flush©}§ 4358 void open( ofstream &, const char name[], const char mode[] = "w" );§\indexc{open}\index{ofstream@©ofstream©!©open©}§ 4359 void close( ofstream & );§\indexc{close}\index{ofstream@©ofstream©!©close©}§ 4360 ofstream & write( ofstream &, const char data[], size_t size );§\indexc{write}\index{ofstream@©ofstream©!©write©}§ 4361 void ?{}( ofstream & );§\index{ofstream@©ofstream©!©?{}©}§ 4362 void ?{}( ofstream &, const char name[], const char mode[] = "w" ); 4363 void ^?{}( ofstream & );§\index{ofstream@©ofstream©!©^?{}©}§ 4364 4365 // *********************************** ifstream *********************************** 4366 bool fail( ifstream & is );§\indexc{fail}\index{ifstream@©ifstream©!©fail©}§ 4367 void clear( ifstream & );§\indexc{clear}\index{ifstream@©ifstream©!©clear©}§ 4368 bool eof( ifstream & is );§\indexc{eof}\index{ifstream@©ifstream©!©eof©}§ 4369 void open( ifstream & is, const char name[], const char mode[] = "r" );§\indexc{open}\index{ifstream@©ifstream©!©open©}§ 4370 void close( ifstream & is );§\indexc{close}\index{ifstream@©ifstream©!©close©}§ 4371 ifstream & read( ifstream & is, char data[], size_t size );§\indexc{read}\index{ifstream@©ifstream©!©read©}§ 4372 ifstream & ungetc( ifstream & is, char c );§\indexc{unget}\index{ifstream@©ifstream©!©unget©}§ 4373 void ?{}( ifstream & is );§\index{ifstream@©ifstream©!©?{}©}§ 4374 void ?{}( ifstream & is, const char name[], const char mode[] = "r" ); 4375 void ^?{}( ifstream & is );§\index{ifstream@©ifstream©!©^?{}©}§ 4376 \end{cfa} 4377 \caption{I/O Stream Functions} 4378 \label{f:IOStreamFunctions} 4379 \end{figure} 4380 4381 \VRef[Figure]{f:CFACommand-LineProcessing} demonstrates the file operations by showing the idiomatic \CFA command-line processing and copying an input file to an output file. 4250 4382 Note, a stream variable may be copied because it is a reference to an underlying stream data-structures. 4251 All I/O errors are handles as exceptions, but end-of-file is not an exception as C programmers are use to explicitly checking for it.4383 \Textbf{All I/O errors are handled as exceptions}, but end-of-file is not an exception as C programmers are use to explicitly checking for it. 4252 4384 4253 4385 \begin{figure} … … 4261 4393 try { 4262 4394 choose ( argc ) { 4263 case 2, 3:4395 case 3, 2: 4264 4396 ®open®( in, argv[1] ); §\C{// open input file first as output creates file}§ 4265 4397 if ( argc == 3 ) ®open®( out, argv[2] ); §\C{// do not create output unless input opens}§ … … 4290 4422 \end{figure} 4291 4423 4292 \VRef[Figure]{f:StreamFunctions} shows the stream operations.4293 \begin{itemize}[topsep=4pt,itemsep=2pt,parsep=0pt]4294 \item4295 \Indexc{fail} tests the stream error-indicator, returning nonzero if it is set.4296 \item4297 \Indexc{clear} resets the stream error-indicator.4298 \item4299 \Indexc{flush} (©ofstream© only) causes any unwritten data for a stream to be written to the file.4300 \item4301 \Indexc{eof} (©ifstream© only) tests the end-of-file indicator for the stream pointed to by stream.4302 Returns true if the end-of-file indicator is set, otherwise false.4303 \item4304 \Indexc{open} binds the file with ©name© to a stream accessed with ©mode© (see ©fopen©).4305 \item4306 \Indexc{close} flushes the stream and closes the file.4307 \item4308 \Indexc{write} (©ofstream© only) writes ©size© bytes to the stream.4309 The bytes are written lazily when an internal buffer fills.4310 Eager buffer writes are done with ©flush©4311 \item4312 \Indexc{read} (©ifstream© only) reads ©size© bytes from the stream.4313 \item4314 \Indexc{ungetc} (©ifstream© only) pushes the character back to the input stream.4315 Pushed-back characters returned by subsequent reads in the reverse order of pushing.4316 \end{itemize}4317 The constructor functions:4318 \begin{itemize}[topsep=4pt,itemsep=2pt,parsep=0pt]4319 \item4320 create an unbound stream, which is subsequently bound to a file with ©open©.4321 \item4322 create a bound stream to the associated file with given ©mode©.4323 \end{itemize}4324 The destructor closes the stream.4325 4326 \begin{figure}4327 \begin{cfa}4328 // *********************************** ofstream ***********************************4329 4330 bool fail( ofstream & );§\indexc{fail}\index{ofstream@©ofstream©!©fail©}§4331 void clear( ofstream & );§\indexc{clear}\index{ofstream@©ofstream©!©clear©}§4332 int flush( ofstream & );§\indexc{flush}\index{ofstream@©ofstream©!©flush©}§4333 void open( ofstream &, const char name[], const char mode[] = "w" );§\indexc{open}\index{ofstream@©ofstream©!©open©}§4334 void close( ofstream & );§\indexc{close}\index{ofstream@©ofstream©!©close©}§4335 ofstream & write( ofstream &, const char data[], size_t size );§\indexc{write}\index{ofstream@©ofstream©!©write©}§4336 4337 void ?{}( ofstream & );§\index{ofstream@©ofstream©!©?{}©}§4338 void ?{}( ofstream &, const char name[], const char mode[] = "w" );4339 void ^?{}( ofstream & );§\index{ofstream@©ofstream©!©^?{}©}§4340 4341 // *********************************** ifstream ***********************************4342 4343 bool fail( ifstream & is );§\indexc{fail}\index{ifstream@©ifstream©!©fail©}§4344 void clear( ifstream & );§\indexc{clear}\index{ifstream@©ifstream©!©clear©}§4345 bool eof( ifstream & is );§\indexc{eof}\index{ifstream@©ifstream©!©eof©}§4346 void open( ifstream & is, const char name[], const char mode[] = "r" );§\indexc{open}\index{ifstream@©ifstream©!©open©}§4347 void close( ifstream & is );§\indexc{close}\index{ifstream@©ifstream©!©close©}§4348 ifstream & read( ifstream & is, char data[], size_t size );§\indexc{read}\index{ifstream@©ifstream©!©read©}§4349 ifstream & ungetc( ifstream & is, char c );§\indexc{unget}\index{ifstream@©ifstream©!©unget©}§4350 4351 void ?{}( ifstream & is );§\index{ifstream@©ifstream©!©?{}©}§4352 void ?{}( ifstream & is, const char name[], const char mode[] = "r" );4353 void ^?{}( ifstream & is );§\index{ifstream@©ifstream©!©^?{}©}§4354 \end{cfa}4355 \caption{Stream Functions}4356 \label{f:StreamFunctions}4357 \end{figure}4358 4359 4424 4360 4425 \subsection{Implicit Separator} 4361 4426 4362 4427 The \Index{implicit separator}\index{I/O!separator} character (space/blank) is a separator not a terminator for output. 4363 The rules for implicitly adding theseparator are:4428 The rules for implicitly adding a separator are: 4364 4429 \begin{enumerate} 4365 4430 \item … … 4390 4455 \begin{cfa} 4391 4456 sout | 1 | ", x" | 2 | ". x" | 3 | "; x" | 4 | "! x" | 5 | "? x" | 6 | "% x" 4392 | 7 | " $\LstStringStyle{\textcent}$ x" | 8 | "$\LstStringStyle{\guillemotright}$x" | 9 | ") x" | 10 | "] x" | 11 | "} x";4457 | 7 | "§\LstStringStyle{\textcent}§ x" | 8 | "§\LstStringStyle{\guillemotright}§ x" | 9 | ") x" | 10 | "] x" | 11 | "} x"; 4393 4458 \end{cfa} 4394 4459 \begin{cfa}[showspaces=true] 4395 1®,® x 2®.® x 3®;® x 4®!® x 5®?® x 6®%® x 7$\R{\LstStringStyle{\textcent}}$ x 8$\R{\LstStringStyle{\guillemotright}}$x 9®)® x 10®]® x 11®}® x4460 Input1®,® x 2®.® x 3®;® x 4®!® x 5®?® x 6®%® x 7§\R{\LstStringStyle{\textcent}}§ x 8§\R{\LstStringStyle{\guillemotright}}§ x 9®)® x 10®]® x 11®}® x 4396 4461 \end{cfa} 4397 4462 4398 4463 \item 4399 4464 A separator does not appear after a C string ending with the (extended) \Index*{ASCII}\index{ASCII!extended} characters: \LstStringStyle{([\{=\$\textsterling\textyen\textexclamdown\textquestiondown\guillemotleft}, where \LstStringStyle{\textexclamdown\textquestiondown} are inverted opening exclamation and question marks, and \LstStringStyle{\guillemotleft} is an opening citation mark. 4400 %$ 4401 \begin{cfa} 4402 sout | "x (" | 1 | "x [" | 2 | "x {" | 3 | "x =" | 4 | "x $\LstStringStyle{\textdollar}$" | 5 | "x $\LstStringStyle{\textsterling}$" | 6 | "x $\LstStringStyle{\textyen}$" 4403 | 7 | "x $\LstStringStyle{\textexclamdown}$" | 8 | "x $\LstStringStyle{\textquestiondown}$" | 9 | "x $\LstStringStyle{\guillemotleft}$" | 10; 4404 \end{cfa} 4405 %$ 4465 \begin{cfa} 4466 sout | "x (" | 1 | "x [" | 2 | "x {" | 3 | "x =" | 4 | "x §\LstStringStyle{\textdollar}§" | 5 | "x §\LstStringStyle{\textsterling}§" | 6 | "x §\LstStringStyle{\textyen}§" 4467 | 7 | "x §\LstStringStyle{\textexclamdown}§" | 8 | "x §\LstStringStyle{\textquestiondown}§" | 9 | "x §\LstStringStyle{\guillemotleft}§" | 10; 4468 \end{cfa} 4406 4469 \begin{cfa}[showspaces=true] 4407 x ®(®1 x ®[®2 x ®{®3 x ®=®4 x $\LstStringStyle{\textdollar}$5 x $\R{\LstStringStyle{\textsterling}}$6 x $\R{\LstStringStyle{\textyen}}$7 x $\R{\LstStringStyle{\textexclamdown}}$8 x $\R{\LstStringStyle{\textquestiondown}}$9 x $\R{\LstStringStyle{\guillemotleft}}$10 4408 \end{cfa} 4409 %$ 4470 x ®(®1 x ®[®2 x ®{®3 x ®=®4 x §\LstStringStyle{\textdollar}§5 x §\R{\LstStringStyle{\textsterling}}§6 x §\R{\LstStringStyle{\textyen}}§7 x §\R{\LstStringStyle{\textexclamdown}}§8 x §\R{\LstStringStyle{\textquestiondown}}§9 x §\R{\LstStringStyle{\guillemotleft}}§10 4471 \end{cfa} 4410 4472 4411 4473 \item … … 4415 4477 \end{cfa} 4416 4478 \begin{cfa}[showspaces=true,showtabs=true] 4417 x®`®1®`®x $\R{\texttt{'}}$2$\R{\texttt{'}}$x$\R{\texttt{"}}$3$\R{\texttt{"}}$x®:®4®:®x® ®5® ®x® ®6® ®x4479 x®`®1®`®x§\R{\texttt{'}}§2§\R{\texttt{'}}§x§\R{\texttt{"}}§3§\R{\texttt{"}}§x®:®4®:®x® ®5® ®x® ®6® ®x 4418 4480 \end{cfa} 4419 4481 … … 4421 4483 If a space is desired before or after one of the special string start/end characters, explicitly insert a space. 4422 4484 \begin{cfa} 4423 sout | "x ( $\R{\texttt{\textvisiblespace}}$" | 1 | "$\R{\texttt{\textvisiblespace}}$) x" | 2 | "$\R{\texttt{\textvisiblespace}}$, x" | 3 | "$\R{\texttt{\textvisiblespace}}$:x:$\R{\texttt{\textvisiblespace}}$" | 4;4485 sout | "x (§\R{\texttt{\textvisiblespace}}§" | 1 | "§\R{\texttt{\textvisiblespace}}§) x" | 2 | "§\R{\texttt{\textvisiblespace}}§, x" | 3 | "§\R{\texttt{\textvisiblespace}}§:x:§\R{\texttt{\textvisiblespace}}§" | 4; 4424 4486 \end{cfa} 4425 4487 \begin{cfa}[showspaces=true,showtabs=true] … … 4438 4500 The separator string can be at most 16 characters including the ©'\0'© string terminator (15 printable characters). 4439 4501 \begin{cfa}[belowskip=0pt] 4440 sepSet( sout, ", $\LstStringStyle{\textdollar}$" ); §\C{// set separator from " " to ", \$"}§4502 sepSet( sout, ", §\LstStringStyle{\textdollar}§" ); §\C{// set separator from " " to ", \$"}§ 4441 4503 sout | 1 | 2 | 3 | " \"" | ®sepVal® | "\""; 4442 4504 \end{cfa} 4443 4505 \begin{cfa}[showspaces=true,aboveskip=0pt] 4444 1®, $\color{red}\LstStringStyle{\textdollar}$®2®, $\color{red}\LstStringStyle{\textdollar}$®3 ®", $\color{red}\LstStringStyle{\textdollar}$"®4506 1®, §\color{red}\LstStringStyle{\textdollar}§®2®, §\color{red}\LstStringStyle{\textdollar}§®3 ®", §\color{red}\LstStringStyle{\textdollar}§"® 4445 4507 \end{cfa} 4446 4508 \begin{cfa}[belowskip=0pt] … … 4557 4619 For example, in: 4558 4620 \begin{cfa} 4621 int i, j; 4559 4622 sin | i | ®nl® | j; 4560 4623 1 ®2® … … 4562 4625 \end{cfa} 4563 4626 variable ©i© is assigned 1, the 2 is skipped, and variable ©j© is assigned 3. 4627 For example, in: 4628 \begin{cquote} 4629 \begin{tabular}{@{}l@{\hspace{3em}}l@{}} 4630 \begin{cfa} 4631 char ch 4632 4633 sin | ch; // read X 4634 4635 X 4636 \end{cfa} 4637 & 4638 \begin{cfa} 4639 4640 sin | ®nlOn®; // enable reading newlines 4641 sin | ch; // read newline 4642 4643 4644 \end{cfa} 4645 \end{tabular} 4646 \end{cquote} 4647 the left example skips the newline and reads ©'X'© into ©ch©, while the right example reads the newline into ©ch©. 4564 4648 4565 4649 For output: … … 4589 4673 4590 4674 4591 \subsection{Output ValueManipulators}4675 \subsection{Output Manipulators} 4592 4676 4593 4677 The following \Index{manipulator}s control formatting (printing) of the argument output values. … … 4643 4727 \item 4644 4728 \Indexc{unit}( engineering-notation )\index{manipulator!unit@©unit©} print engineering exponent as a letter between the range $10^{-24}$ and $10^{24}$: 4729 \begin{cquote} 4645 4730 ©y© $\Rightarrow 10^{-24}$, ©z© $\Rightarrow 10^{-21}$, ©a© $\Rightarrow 10^{-18}$, ©f© $\Rightarrow 10^{-15}$, ©p© $\Rightarrow 10^{-12}$, ©n© $\Rightarrow 10^{-9}$, ©u© $\Rightarrow 10^{-6}$, ©m© $\Rightarrow 10^{-3}$, ©K© $\Rightarrow 10^{3}$, ©M© $\Rightarrow 10^{6}$, ©G© $\Rightarrow 10^{9}$, ©T© $\Rightarrow 10^{12}$, ©P© $\Rightarrow 10^{15}$, ©E© $\Rightarrow 10^{18}$, ©Z© $\Rightarrow 10^{21}$, ©Y© $\Rightarrow 10^{24}$. 4731 \end{cquote} 4646 4732 For exponent $10^{0}$, no decimal point or letter is printed. 4647 4733 \begin{cfa}[belowskip=0pt] … … 4843 4929 // End: // 4844 4930 \end{comment} 4845 %$ 4846 4847 4848 \subsection{Input Value Manipulators} 4849 4850 The format of numeric input values in the same as C constants without a trailing type suffix, as the input value-type is denoted by the input variable. 4851 For ©bool© type, the constants are ©true© and ©false©. 4852 For integral types, any number of digits, optionally preceded by a sign (©+© or ©-©), where a 4853 \begin{itemize} 4854 \item 4855 ©1©-©9© prefix introduces a decimal value (©0©-©9©), 4856 \item 4857 ©0© prefix introduces an octal value (©0©-©7©), and 4858 \item 4859 ©0x© or ©0X© prefix introduces a hexadecimal value (©0©-©f©) with lower or upper case letters. 4860 \end{itemize} 4861 For floating-point types, any number of decimal digits, optionally preceded by a sign (©+© or ©-©), optionally containing a decimal point, and optionally followed by an exponent, ©e© or ©E©, with signed (optional) decimal digits. 4862 Floating-point values can also be written in hexadecimal format preceded by ©0x© or ©0X© with hexadecimal digits and exponent denoted by ©p© or ©P©. 4863 4864 For the C-string type, the input values are \emph{not} the same as C-string constants, \ie double quotes bracketing arbitrary text with escape sequences. 4865 Instead, the next sequence of non-whitespace characters are read, and the input sequence is terminated with delimiter ©'\0'©. 4866 The string variable \emph{must} be large enough to contain the input sequence. 4931 4932 4933 \subsection{Input Manipulators} 4934 4935 The following \Index{manipulator}s control scanning of input values (reading), and only affect the format of the argument. 4936 4937 Certain manipulators support a \newterm{scanset}, which is a simple regular expression, where the matching set contains any Latin-1 character (8-bits) or character ranges using minus. 4938 For example, the scanset \lstinline{"a-zA-Z -/?§"} matches any number of characters between ©'a'© and ©'z'©, between ©'A'© and ©'Z'©, between space and ©'/'©, and characters ©'?'© and (Latin-1) ©'§'©. 4939 The following string is matched by this scanset: 4940 \begin{cfa} 4941 !&%$ abAA () ZZZ ?? xx§\S\S\S§ 4942 \end{cfa} 4943 To match a minus, put it as the first character, ©"-0-9"©. 4944 Other complex forms of regular-expression matching are not supported. 4945 4946 A string variable \emph{must} be large enough to contain the input sequence. 4867 4947 To force programmers to consider buffer overruns for C-string input, C-strings can only be read with a width field, which should specify a size less than or equal to the C-string size, \eg: 4868 4948 \begin{cfa} … … 4871 4951 \end{cfa} 4872 4952 4873 A scanset is a simple regular expression, where the matching set contains any Latin-1 character (8-bits) or character ranges using minus. 4874 For example, the scanset \lstinline{"a-zA-Z -/?§"} matches characters between ©'a'© and ©'z'©, between ©'A'© and ©'Z'©, between space and ©'/'©, and characters ©'?'© and (Latin-1) ©'§'©. 4875 The following string is matched by this scanset: 4876 \begin{cfa} 4877 !&%$ abAA () ZZZ ?? xx§§§§ 4878 \end{cfa} 4879 To match a minus, put it as the first character, ©"-0-9"©. 4880 Other complex forms of regular-expression matching are not supported. 4881 4882 The following \Index{manipulator}s control scanning of input values (reading), and only affect the format of the argument. 4953 Currently, there is no mechanism to detect if a value read exceeds the capwhen Most types are finite sized, \eg integral types only store value that fit into their corresponding storage, 8, 16, 32, 64, 128 bits. 4954 Hence, an input value may be too large, and the result of the read is often considered undefined, which leads to difficlt to locate runtime errors. 4955 All reads in \CFA check if values do not fit into the argument variable's type and raise the exception 4956 All types are 4957 4883 4958 \begin{enumerate} 4884 4959 \item 4885 \Indexc{skip}( pattern )\index{manipulator!skip@©skip©}, ©skip©( length)4886 The pattern is composed of white-space and non-white-space characters, where \emph{any} white-space character matches 0 or more input white-space characters (hence, consecutive white-space characters in the pattern are combined), and each non-white-space character matches exactly with an input character.4887 The length is composed of the next $N$ characters, including the newline character.4960 \Indexc{skip}( scanset )\index{manipulator!skip@©skip©}, ©skip©( $N$ ) 4961 The first form uses a scanset to skip matching characters. 4962 The second form skips the next $N$ characters, including newline. 4888 4963 If the match successes, the input characters are discarded, and input continues with the next character. 4889 4964 If the match fails, the input characters are left unread. 4890 4965 \begin{cfa}[belowskip=0pt] 4891 char sk[ $\,$] = "abc";4966 char sk[§\,§] = "abc"; 4892 4967 sin | "abc " | skip( sk ) | skip( 5 ); // match input sequence 4893 4968 \end{cfa} … … 4899 4974 4900 4975 \item 4901 \Indexc{wdi}( maximum, reference-value )\index{manipulator!wdi@©wdi©} 4902 For all types except ©char©, maximum is the maximum number of characters read for the current operation. 4976 \Indexc{wdi}( maximum, variable )\index{manipulator!wdi@©wdi©} 4977 For all types except ©char *©, whitespace is skipped until an appropriate value is found for the specified variable type. 4978 maximum is the maximum number of characters read for the current operation. 4903 4979 \begin{cfa}[belowskip=0pt] 4904 char s[10]; int i; double d;4905 sin | wdi( 4, s ) | wdi( 3, i ) | wdi( 8, d ); // c == "abcd", i == 123, d == 3.456E+24980 char ch; char ca[3]; int i; double d; 4981 sin | wdi( sizeof(ch), ch ) | wdi( sizeof(ca), ca[0] ) | wdi( 3, i ) | wdi( 8, d ); // c == 'a', ca == "bcd", i == 123, d == 345.6 4906 4982 \end{cfa} 4907 4983 \begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt] 4908 4984 ®abcd1233.456E+2® 4909 4985 \end{cfa} 4986 Here, ©ca[0]© is type ©char©, so the width reads 3 characters \Textbf{without} a null terminator. 4987 4910 4988 Note, input ©wdi© cannot be overloaded with output ©wd© because both have the same parameters but return different types. 4911 4989 Currently, \CFA cannot distinguish between these two manipulators in the middle of an ©sout©/©sin© expression based on return type. 4990 4991 \item 4992 \Indexc{wdi}( maximum size, ©char s[]© )\index{manipulator!wdi@©wdi©} 4993 For type ©char *©, maximum is the maximum number of characters read for the current operation. 4994 Any number of non-whitespace characters, stopping at the first whitespace character found. A terminating null character is automatically added at the end of the stored sequence 4995 \begin{cfa}[belowskip=0pt] 4996 char cstr[10]; 4997 sin | wdi( sizeof(cstr), cstr ); 4998 \end{cfa} 4999 \begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt] 5000 ®abcd1233.456E+2® 5001 \end{cfa} 5002 5003 \item 5004 \Indexc{wdi}( maximum size, maximum read, ©char s[]© )\index{manipulator!wdi@©wdi©} 5005 For type ©char *©, maximum is the maximum number of characters read for the current operation. 5006 \begin{cfa}[belowskip=0pt] 5007 char ch; char ca[3]; int i; double d; 5008 sin | wdi( sizeof(ch), ch ) | wdi( sizeof(ca), ca[0] ) | wdi( 3, i ) | wdi( 8, d ); // c == 'a', ca == "bcd", i == 123, d == 345.6 5009 \end{cfa} 5010 \begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt] 5011 ®abcd1233.456E+2® 5012 \end{cfa} 4912 5013 4913 5014 \item … … 4946 5047 \end{cfa} 4947 5048 5049 \Indexc{quoted}( char delimit, wdi-input-string )\index{manipulator!quoted@©quoted©} 5050 Is an ©excl© with scanset ©"delimit"©, which consumes all characters up to the delimit character. 5051 If the delimit character is omitted, it defaults to ©'\n'© (newline). 5052 4948 5053 \item 4949 5054 \Indexc{getline}( char delimit, wdi-input-string )\index{manipulator!getline@©getline©} 4950 Is an @excl@with scanset ©"delimit"©, which consumes all characters up to the delimit character.5055 Is an ©excl© with scanset ©"delimit"©, which consumes all characters up to the delimit character. 4951 5056 If the delimit character is omitted, it defaults to ©'\n'© (newline). 4952 5057 \end{enumerate} … … 4958 5063 For example, if two threads execute the following: 4959 5064 \begin{cfa} 4960 $\emph{thread\(_1\)}$: sout | "abc " | "def ";4961 $\emph{thread\(_2\)}$: sout | "uvw " | "xyz ";5065 §\emph{thread\(_1\)}§ : sout | "abc " | "def "; 5066 §\emph{thread\(_2\)}§ : sout | "uvw " | "xyz "; 4962 5067 \end{cfa} 4963 5068 possible outputs are: … … 4999 5104 The common usage is the short form of the mutex statement\index{ostream@©ostream©!mutex@©mutex©} to lock a stream during a single cascaded I/O expression, \eg: 5000 5105 \begin{cfa} 5001 $\emph{thread\(_1\)}$: ®mutex( sout )® sout | "abc " | "def ";5002 $\emph{thread\(_2\)}$: ®mutex( sout )® sout | "uvw " | "xyz ";5106 §\emph{thread\(_1\)}§ : ®mutex( sout )® sout | "abc " | "def "; 5107 §\emph{thread\(_2\)}§ : ®mutex( sout )® sout | "uvw " | "xyz "; 5003 5108 \end{cfa} 5004 5109 Now, the order of the thread execution is still non-deterministic, but the output is constrained to two possible lines in either order. … … 5061 5166 Cultures use different syntax, called a \newterm{locale}, for printing numbers so they are easier to read, \eg: 5062 5167 \begin{cfa} 5063 12®,®345®.®123 $\C[1.25in]{// comma separator, period decimal-point}$5168 12®,®345®.®123 §\C[1.25in]{// comma separator, period decimal-point}§ 5064 5169 12®.®345®,®123 §\C{// period separator, comma decimal-point}§ 5065 12 $\Sp$345®,®123®.® §\C{// space separator, comma decimal-point, period terminator}\CRT§5170 12§\Sp§345®,®123®.® §\C{// space separator, comma decimal-point, period terminator}\CRT§ 5066 5171 \end{cfa} 5067 5172 A locale is selected with function ©setlocale©, and the corresponding locale package \emph{must} be installed on the underlying system; … … 5109 5214 Ukraine uk_UA.utf8 5110 5215 12 123 1 234 12 345 123 456 1 234 567 5111 12®.® 123®,®1®.® 1 $\Sp$234®,®12®.® 12$\Sp$ 345®,®123®.® 123$\Sp$ 456®,®1234®.® 1$\Sp$ 234$\Sp$567®,®12345®.®5216 12®.® 123®,®1®.® 1§\Sp§234®,®12®.® 12§\Sp§ 345®,®123®.® 123§\Sp§ 456®,®1234®.® 1§\Sp§ 234§\Sp§567®,®12345®.® 5112 5217 5113 5218 Default locale off C … … 5461 5566 5462 5567 \subsection{Operator} 5568 \label{s:Operator} 5463 5569 5464 5570 \CFA also allows operators to be overloaded, to simplify the use of user-defined types. … … 7332 7438 7333 7439 \Index*[C++]{\CC{}} is a general-purpose programming language. 7334 It has imperative, object-oriented and generic programming features, while also providing facilities for low-level memory manipulation. (Wikipedia) 7335 7336 The primary focus of \CC seems to be adding object-oriented programming to C, and this is the primary difference between \CC and Do. 7440 It is an imperative, object-oriented and generic programming language, while also providing facilities for low-level memory manipulation. 7441 The primary focus of \CC was adding object-oriented programming to C, and this is the primary difference between \CC and \CFA. 7337 7442 \CC uses classes to encapsulate data and the functions that operate on that data, and to hide the internal representation of the data. 7338 7443 \CFA uses modules instead to perform these same tasks. … … 7352 7457 \subsection{Go} 7353 7458 7354 \Index*{Go}, also commonly referred to as golang, is a programming language developed at Google in 2007 [.].7459 \Index*{Go}, also commonly referred to as golang, is a programming language developed at Google in 2007~\cite{Go}. 7355 7460 It is a statically typed language with syntax loosely derived from that of C, adding garbage collection, type 7356 7461 safety, some structural typing capabilities, additional built-in types such as variable-length arrays and key-value maps, and a large standard library. (Wikipedia) … … 7406 7511 In \CFA, there are ambiguous cases with dereference and operator identifiers, \eg ©int *?*?()©, where the string ©*?*?© can be interpreted as: 7407 7512 \begin{cfa} 7408 *? $\Sp$*?§\C{// dereference operator, dereference operator}§7409 * $\Sp$?*?§\C{// dereference, multiplication operator}§7513 *?§\Sp§*? §\C{// dereference operator, dereference operator}§ 7514 *§\Sp§?*? §\C{// dereference, multiplication operator}§ 7410 7515 \end{cfa} 7411 7516 By default, the first interpretation is selected, which does not yield a meaningful parse. … … 7416 7521 The ambiguity occurs when the deference operator has no parameters: 7417 7522 \begin{cfa} 7418 *?() $\R{\textvisiblespace...}$;7419 *?() $\R{\textvisiblespace...}$(...) ;7523 *?()§\R{\textvisiblespace...}§ ; 7524 *?()§\R{\textvisiblespace...}§(...) ; 7420 7525 \end{cfa} 7421 7526 requiring arbitrary whitespace look-ahead for the routine-call parameter-list to disambiguate. … … 7425 7530 The remaining cases are with the increment/decrement operators and conditional expression, \eg: 7426 7531 \begin{cfa} 7427 i++? $\R{\textvisiblespace...}$(...);7428 i?++ $\R{\textvisiblespace...}$(...);7532 i++?§\R{\textvisiblespace...}§(...); 7533 i?++§\R{\textvisiblespace...}§(...); 7429 7534 \end{cfa} 7430 7535 requiring arbitrary whitespace look-ahead for the operator parameter-list, even though that interpretation is an incorrect expression (juxtaposed identifiers). 7431 7536 Therefore, it is necessary to disambiguate these cases with a space: 7432 7537 \begin{cfa} 7433 i++ $\Sp$? i : 0;7434 i? $\Sp$++i : 0;7538 i++§\Sp§? i : 0; 7539 i?§\Sp§++i : 0; 7435 7540 \end{cfa} 7436 7541 … … 7459 7564 \eg: 7460 7565 \begin{cfa} 7461 x; 7462 *y; §\C{// int *y}§7463 f( p1, p2 ); 7464 g( p1, p2 ) int p1, p2; 7566 x; §\C{// int x}§ 7567 *y; §\C{// int * y}§ 7568 f( p1, p2 ); §\C{// int f( int p1, int p2 );}§ 7569 g( p1, p2 ) int p1, p2; §\C{// int g( int p1, int p2 );}§ 7465 7570 \end{cfa} 7466 7571 \CFA continues to support K\&R routine definitions: 7467 7572 \begin{cfa} 7468 f( a, b, c ) 7469 int a, b; char c 7573 f( a, b, c ) §\C{// default int return}§ 7574 int a, b; char c; §\C{// K\&R parameter declarations}§ 7470 7575 { 7471 7576 ... … … 7486 7591 int rtn( int i ); 7487 7592 int rtn( char c ); 7488 rtn( 'x' ); 7593 rtn( 'x' ); §\C{// programmer expects 2nd rtn to be called}§ 7489 7594 \end{cfa} 7490 7595 \item[Rationale:] it is more intuitive for the call to ©rtn© to match the second version of definition of ©rtn© rather than the first. … … 7508 7613 \item[Change:] make string literals ©const©: 7509 7614 \begin{cfa} 7510 char * p = "abc"; 7511 char * q = expr ? "abc" : "de"; 7615 char * p = "abc"; §\C{// valid in C, deprecated in \CFA}§ 7616 char * q = expr ? "abc" : "de"; §\C{// valid in C, invalid in \CFA}§ 7512 7617 \end{cfa} 7513 7618 The type of a string literal is changed from ©[] char© to ©const [] char©. … … 7516 7621 \begin{cfa} 7517 7622 char * p = "abc"; 7518 p[0] = 'w'; 7623 p[0] = 'w'; §\C{// segment fault or change constant literal}§ 7519 7624 \end{cfa} 7520 7625 The same problem occurs when passing a string literal to a routine that changes its argument. … … 7528 7633 \item[Change:] remove \newterm{tentative definitions}, which only occurs at file scope: 7529 7634 \begin{cfa} 7530 int i; 7531 int *j = ®&i®; 7532 int i = 0; 7635 int i; §\C{// forward definition}§ 7636 int *j = ®&i®; §\C{// forward reference, valid in C, invalid in \CFA}§ 7637 int i = 0; §\C{// definition}§ 7533 7638 \end{cfa} 7534 7639 is valid in C, and invalid in \CFA because duplicate overloaded object definitions at the same scope level are disallowed. … … 7536 7641 \begin{cfa} 7537 7642 struct X { int i; struct X *next; }; 7538 static struct X a; 7539 static struct X b = { 0, ®&a® }; §\C{// forward reference, valid in C, invalid in \CFA}§7540 static struct X a = { 1, &b }; 7643 static struct X a; §\C{// forward definition}§ 7644 static struct X b = { 0, ®&a® }; §\C{// forward reference, valid in C, invalid in \CFA}§ 7645 static struct X a = { 1, &b }; §\C{// definition}§ 7541 7646 \end{cfa} 7542 7647 \item[Rationale:] avoids having different initialization rules for builtin types and user-defined types. … … 7552 7657 enum ®Colour® { R, G, B, Y, C, M }; 7553 7658 struct Person { 7554 enum ®Colour® { R, G, B }; $\C[7cm]{// nested type}$7555 struct Face { 7556 ®Colour® Eyes, Hair; 7659 enum ®Colour® { R, G, B }; §\C{// nested type}§ 7660 struct Face { §\C{// nested type}§ 7661 ®Colour® Eyes, Hair; §\C{// type defined outside (1 level)}§ 7557 7662 }; 7558 ®.Colour® shirt; 7559 ®Colour® pants; 7560 Face looks[10]; 7663 ®.Colour® shirt; §\C{// type defined outside (top level)}§ 7664 ®Colour® pants; §\C{// type defined same level}§ 7665 Face looks[10]; §\C{// type defined same level}§ 7561 7666 }; 7562 ®Colour® c = R; 7563 Person®.Colour® pc = Person®.®R; §\C{// type/enum defined inside}§7564 Person®.®Face pretty; §\C{// type defined inside}\CRT§7667 ®Colour® c = R; §\C{// type/enum defined same level}§ 7668 Person®.Colour® pc = Person®.®R; §\C{// type/enum defined inside}§ 7669 Person®.®Face pretty; §\C{// type defined inside}§ 7565 7670 \end{cfa} 7566 7671 In C, the name of the nested types belongs to the same scope as the name of the outermost enclosing structure, \ie the nested types are hoisted to the scope of the outer-most type, which is not useful and confusing. … … 7639 7744 \CFA introduces the following new \Index{keyword}s, which cannot be used as identifiers. 7640 7745 7746 \begin{cquote} 7747 \Indexc{basetypeof}, \Indexc{choose}, \Indexc{coroutine}, \Indexc{disable}, 7748 \Indexc{enable}, \Indexc{exception}, \Indexc{fallthrough}, \Indexc{fallthru}, 7749 \Indexc{finally}, \Indexc{fixup}, \Indexc{forall},\Indexc{generator}, 7750 \Indexc{int128}, \Indexc{monitor}, \Indexc{mutex}, \Indexc{one_t}, 7751 \Indexc{report}, \Indexc{suspend}, \Indexc{throw}, \Indexc{throwResume}, 7752 \Indexc{trait}, \Indexc{try}, \Indexc{virtual}, \Indexc{waitfor}, 7753 \Indexc{when}, \Indexc{with}, \Indexc{zero_t} 7754 \end{cquote} 7755 \CFA introduces the following new \Index{quasi-keyword}s, which can be used as identifiers. 7756 \begin{cquote} 7757 \Indexc{catch}, \Indexc{catchResume}, \Indexc{finally}, \Indexc{fixup}, \Indexc{or}, \Indexc{timeout} 7758 \end{cquote} 7759 7760 \begin{comment} 7641 7761 \begin{cquote} 7642 7762 \begin{tabular}{@{}lllllll@{}} … … 7707 7827 \end{tabular} 7708 7828 \end{cquote} 7829 \end{comment} 7830 7709 7831 7710 7832 \section{Standard Headers} 7711 7833 \label{s:StandardHeaders} 7712 7834 7713 \Celeven prescribes the following standard header-files~\cite[\S~7.1.2]{C11} and \CFA adds to this list: 7835 \Celeven prescribes the following standard header-files~\cite[\S~7.1.2]{C11}: 7836 \begin{cquote} 7837 \Indexc{assert.h}, \Indexc{complex.h}, \Indexc{ctype.h}, \Indexc{errno.h}, \Indexc{fenv.h}, 7838 \Indexc[deletekeywords=float]{float.h}, \Indexc{inttypes.h}, \Indexc{iso646.h}, \Indexc{limits.h}, 7839 \Indexc{locale.h}, \Indexc{math.h}, \Indexc{setjmp.h}, \Indexc{signal.h}, \Indexc{stdalign.h}, 7840 \Indexc{stdarg.h}, \Indexc{stdatomic.h}, \Indexc{stdbool.h}, \Indexc{stddef.h}, \Indexc{stdint.h}, 7841 \Indexc{stdio.h}, \Indexc{stdlib.h}, \Indexc{stdnoreturn.h}, \Indexc{string.h}, \Indexc{tgmath.h}, 7842 \Indexc{threads.h}, \Indexc{time.h}, \Indexc{uchar.h}, \Indexc{wchar.h}, \Indexc{wctype.h} 7843 \end{cquote} 7844 and \CFA adds to this list: 7845 \begin{cquote} 7846 \Indexc{gmp.h}, \Indexc{malloc.h}, \Indexc{unistd.h} 7847 \end{cquote} 7848 \begin{comment} 7714 7849 \begin{cquote} 7715 7850 \begin{tabular}{@{}llllll|l@{}} … … 7773 7908 \end{tabular} 7774 7909 \end{cquote} 7910 \end{comment} 7775 7911 For the prescribed head-files, \CFA uses header interposition to wraps these includes in an ©extern "C"©; 7776 7912 hence, names in these include files are not mangled\index{mangling!name} \see{\VRef{s:Interoperability}}. … … 7837 7973 Type-safe allocation is provided for all C allocation routines and new \CFA allocation routines, \eg in 7838 7974 \begin{cfa} 7839 int * ip = (int *)malloc( sizeof(int) ); 7840 int * ip = malloc(); 7841 int * ip = alloc(); 7975 int * ip = (int *)malloc( sizeof(int) ); §\C{// C}§ 7976 int * ip = malloc(); §\C{// \CFA type-safe version of C malloc}§ 7977 int * ip = alloc(); §\C{// \CFA type-safe uniform alloc}§ 7842 7978 \end{cfa} 7843 7979 the latter two allocations determine the allocation size from the type of ©p© (©int©) and cast the pointer to the allocated storage to ©int *©. … … 7846 7982 \begin{cfa} 7847 7983 struct S { int i; } __attribute__(( aligned( 128 ) )); // cache-line alignment 7848 S * sp = malloc(); 7984 S * sp = malloc(); §\C{// honour type alignment}§ 7849 7985 \end{cfa} 7850 7986 the storage allocation is implicitly aligned to 128 rather than the default 16. … … 7861 7997 \CFA memory management extends allocation to support constructors for initialization of allocated storage, \eg in 7862 7998 \begin{cfa} 7863 struct S { int i; }; 7999 struct S { int i; }; §\C{// cache-line alignment}§ 7864 8000 void ?{}( S & s, int i ) { s.i = i; } 7865 8001 // assume ?|? operator for printing an S 7866 8002 7867 S & sp = *®new®( 3 ); 8003 S & sp = *®new®( 3 ); §\C{// call constructor after allocation}§ 7868 8004 sout | sp.i; 7869 8005 ®delete®( &sp ); 7870 8006 7871 S * spa = ®anew®( 10, 5 ); 8007 S * spa = ®anew®( 10, 5 ); §\C{// allocate array and initialize each array element}§ 7872 8008 for ( i; 10 ) sout | spa[i] | nonl; 7873 8009 sout | nl; … … 7881 8017 extern "C" { 7882 8018 // C unsafe allocation 7883 void * malloc( size_t size ); $\indexc{malloc}$7884 void * calloc( size_t dim, size_t size ); $\indexc{calloc}$7885 void * realloc( void * ptr, size_t size ); $\indexc{realloc}$7886 void * memalign( size_t align, size_t size ); $\indexc{memalign}$7887 void * aligned_alloc( size_t align, size_t size ); $\indexc{aligned_alloc}$7888 int posix_memalign( void ** ptr, size_t align, size_t size ); $\indexc{posix_memalign}$7889 void * cmemalign( size_t alignment, size_t noOfElems, size_t elemSize ); $\indexc{cmemalign}$// CFA8019 void * malloc( size_t size );§\indexc{malloc}§ 8020 void * calloc( size_t dim, size_t size );§\indexc{calloc}§ 8021 void * realloc( void * ptr, size_t size );§\indexc{realloc}§ 8022 void * memalign( size_t align, size_t size );§\indexc{memalign}§ 8023 void * aligned_alloc( size_t align, size_t size );§\indexc{aligned_alloc}§ 8024 int posix_memalign( void ** ptr, size_t align, size_t size );§\indexc{posix_memalign}§ 8025 void * cmemalign( size_t alignment, size_t noOfElems, size_t elemSize );§\indexc{cmemalign}§ // CFA 7890 8026 7891 8027 // C unsafe initialization/copy 7892 void * memset( void * dest, int c, size_t size ); $\indexc{memset}$7893 void * memcpy( void * dest, const void * src, size_t size ); $\indexc{memcpy}$8028 void * memset( void * dest, int c, size_t size );§\indexc{memset}§ 8029 void * memcpy( void * dest, const void * src, size_t size );§\indexc{memcpy}§ 7894 8030 } 7895 8031 … … 7897 8033 7898 8034 forall( dtype T | sized(T) ) { 7899 // $\CFA$safe equivalents, i.e., implicit size specification8035 // §\CFA§ safe equivalents, i.e., implicit size specification 7900 8036 T * malloc( void ); 7901 8037 T * calloc( size_t dim ); … … 7906 8042 int posix_memalign( T ** ptr, size_t align ); 7907 8043 7908 // $\CFA$safe general allocation, fill, resize, alignment, array7909 T * alloc( void ); $\indexc{alloc}$ $\C[3.5in]{// variable, T size}$8044 // §\CFA§ safe general allocation, fill, resize, alignment, array 8045 T * alloc( void );§\indexc{alloc}§ §\C[3.5in]{// variable, T size}§ 7910 8046 T * alloc( size_t dim ); §\C{// array[dim], T size elements}§ 7911 8047 T * alloc( T ptr[], size_t dim ); §\C{// realloc array[dim], T size elements}§ 7912 8048 7913 T * alloc_set( char fill ); $\indexc{alloc_set}$§\C{// variable, T size, fill bytes with value}§8049 T * alloc_set( char fill );§\indexc{alloc_set}§ §\C{// variable, T size, fill bytes with value}§ 7914 8050 T * alloc_set( T fill ); §\C{// variable, T size, fill with value}§ 7915 8051 T * alloc_set( size_t dim, char fill ); §\C{// array[dim], T size elements, fill bytes with value}§ … … 7930 8066 T * alloc_align_set( T ptr[], size_t align, size_t dim, char fill ); §\C{// realloc new aligned array[dim], fill new bytes with value}§ 7931 8067 7932 // $\CFA$safe initialization/copy, i.e., implicit size specification7933 T * memset( T * dest, char fill ); $\indexc{memset}$7934 T * memcpy( T * dest, const T * src ); $\indexc{memcpy}$7935 7936 // $\CFA$safe initialization/copy, i.e., implicit size specification, array types8068 // §\CFA§ safe initialization/copy, i.e., implicit size specification 8069 T * memset( T * dest, char fill );§\indexc{memset}§ 8070 T * memcpy( T * dest, const T * src );§\indexc{memcpy}§ 8071 8072 // §\CFA§ safe initialization/copy, i.e., implicit size specification, array types 7937 8073 T * amemset( T dest[], char fill, size_t dim ); 7938 8074 T * amemcpy( T dest[], const T src[], size_t dim ); 7939 8075 } 7940 8076 7941 // $\CFA$allocation/deallocation and constructor/destructor, non-array types7942 forall( dtype T | sized(T), ttype Params | { void ?{}( T &, Params ); } ) T * new( Params p ); $\indexc{new}$7943 forall( dtype T | sized(T) | { void ^?{}( T & ); } ) void delete( T * ptr ); $\indexc{delete}$8077 // §\CFA§ allocation/deallocation and constructor/destructor, non-array types 8078 forall( dtype T | sized(T), ttype Params | { void ?{}( T &, Params ); } ) T * new( Params p );§\indexc{new}§ 8079 forall( dtype T | sized(T) | { void ^?{}( T & ); } ) void delete( T * ptr );§\indexc{delete}§ 7944 8080 forall( dtype T, ttype Params | sized(T) | { void ^?{}( T & ); void delete( Params ); } ) 7945 8081 void delete( T * ptr, Params rest ); 7946 8082 7947 // $\CFA$allocation/deallocation and constructor/destructor, array types7948 forall( dtype T | sized(T), ttype Params | { void ?{}( T &, Params ); } ) T * anew( size_t dim, Params p ); $\indexc{anew}$7949 forall( dtype T | sized(T) | { void ^?{}( T & ); } ) void adelete( size_t dim, T arr[] ); $\indexc{adelete}$8083 // §\CFA§ allocation/deallocation and constructor/destructor, array types 8084 forall( dtype T | sized(T), ttype Params | { void ?{}( T &, Params ); } ) T * anew( size_t dim, Params p );§\indexc{anew}§ 8085 forall( dtype T | sized(T) | { void ^?{}( T & ); } ) void adelete( size_t dim, T arr[] );§\indexc{adelete}§ 7950 8086 forall( dtype T | sized(T) | { void ^?{}( T & ); }, ttype Params | { void adelete( Params ); } ) 7951 8087 void adelete( size_t dim, T arr[], Params rest ); … … 7957 8093 \leavevmode 7958 8094 \begin{cfa}[aboveskip=0pt,belowskip=0pt] 7959 int ato( const char * ptr ); $\indexc{ato}$8095 int ato( const char * ptr );§\indexc{ato}§ 7960 8096 unsigned int ato( const char * ptr ); 7961 8097 long int ato( const char * ptr ); … … 7990 8126 \begin{cfa}[aboveskip=0pt,belowskip=0pt] 7991 8127 forall( T | { int ?<?( T, T ); } ) §\C{// location}§ 7992 T * bsearch( T key, const T * arr, size_t dim ); $\indexc{bsearch}$8128 T * bsearch( T key, const T * arr, size_t dim );§\indexc{bsearch}§ 7993 8129 7994 8130 forall( T | { int ?<?( T, T ); } ) §\C{// position}§ … … 7996 8132 7997 8133 forall( T | { int ?<?( T, T ); } ) 7998 void qsort( const T * arr, size_t dim ); $\indexc{qsort}$8134 void qsort( const T * arr, size_t dim );§\indexc{qsort}§ 7999 8135 8000 8136 forall( E | { int ?<?( E, E ); } ) { 8001 E * bsearch( E key, const E * vals, size_t dim ); $\indexc{bsearch}$§\C{// location}§8137 E * bsearch( E key, const E * vals, size_t dim );§\indexc{bsearch}§ §\C{// location}§ 8002 8138 size_t bsearch( E key, const E * vals, size_t dim );§\C{// position}§ 8003 E * bsearchl( E key, const E * vals, size_t dim ); $\indexc{bsearchl}$8139 E * bsearchl( E key, const E * vals, size_t dim );§\indexc{bsearchl}§ 8004 8140 size_t bsearchl( E key, const E * vals, size_t dim ); 8005 E * bsearchu( E key, const E * vals, size_t dim ); $\indexc{bsearchu}$8141 E * bsearchu( E key, const E * vals, size_t dim );§\indexc{bsearchu}§ 8006 8142 size_t bsearchu( E key, const E * vals, size_t dim ); 8007 8143 } … … 8017 8153 8018 8154 forall( E | { int ?<?( E, E ); } ) { 8019 void qsort( E * vals, size_t dim ); $\indexc{qsort}$8155 void qsort( E * vals, size_t dim );§\indexc{qsort}§ 8020 8156 } 8021 8157 \end{cfa} … … 8026 8162 \leavevmode 8027 8163 \begin{cfa}[aboveskip=0pt,belowskip=0pt] 8028 unsigned char abs( signed char ); $\indexc{abs}$8164 unsigned char abs( signed char );§\indexc{abs}§ 8029 8165 int abs( int ); 8030 8166 unsigned long int abs( long int ); … … 8041 8177 8042 8178 8043 \subsection{ Random Numbers}8179 \subsection{C Random Numbers} 8044 8180 8045 8181 \leavevmode 8046 8182 \begin{cfa}[aboveskip=0pt,belowskip=0pt] 8047 void srandom( unsigned int seed ); $\indexc{srandom}$8048 char random( void ); $\indexc{random}$8183 void srandom( unsigned int seed );§\indexc{srandom}§ 8184 char random( void );§\indexc{random}§ 8049 8185 char random( char u ); §\C{// [0,u)}§ 8050 8186 char random( char l, char u ); §\C{// [l,u]}§ … … 8073 8209 \leavevmode 8074 8210 \begin{cfa}[aboveskip=0pt,belowskip=0pt] 8075 forall( T | { int ?<?( T, T ); } ) T min( T t1, T t2 ); $\indexc{min}$8076 forall( T | { int ?>?( T, T ); } ) T max( T t1, T t2 ); $\indexc{max}$8077 forall( T | { T min( T, T ); T max( T, T ); } ) T clamp( T value, T min_val, T max_val ); $\indexc{clamp}$8078 forall( T ) void swap( T * t1, T * t2 ); $\indexc{swap}$8211 forall( T | { int ?<?( T, T ); } ) T min( T t1, T t2 );§\indexc{min}§ 8212 forall( T | { int ?>?( T, T ); } ) T max( T t1, T t2 );§\indexc{max}§ 8213 forall( T | { T min( T, T ); T max( T, T ); } ) T clamp( T value, T min_val, T max_val );§\indexc{clamp}§ 8214 forall( T ) void swap( T * t1, T * t2 );§\indexc{swap}§ 8079 8215 \end{cfa} 8080 8216 … … 8090 8226 \leavevmode 8091 8227 \begin{cfa}[aboveskip=0pt,belowskip=0pt] 8092 float ?%?( float, float ); $\indexc{fmod}$8228 float ?%?( float, float );§\indexc{fmod}§ 8093 8229 float fmod( float, float ); 8094 8230 double ?%?( double, double ); … … 8097 8233 long double fmod( long double, long double ); 8098 8234 8099 float remainder( float, float ); $\indexc{remainder}$8235 float remainder( float, float );§\indexc{remainder}§ 8100 8236 double remainder( double, double ); 8101 8237 long double remainder( long double, long double ); 8102 8238 8103 float remquo( float, float, int * ); $\indexc{remquo}$8239 float remquo( float, float, int * );§\indexc{remquo}§ 8104 8240 double remquo( double, double, int * ); 8105 8241 long double remquo( long double, long double, int * ); … … 8112 8248 [ int, long double ] div( long double, long double ); 8113 8249 8114 float fma( float, float, float ); $\indexc{fma}$8250 float fma( float, float, float );§\indexc{fma}§ 8115 8251 double fma( double, double, double ); 8116 8252 long double fma( long double, long double, long double ); 8117 8253 8118 float fdim( float, float ); $\indexc{fdim}$8254 float fdim( float, float );§\indexc{fdim}§ 8119 8255 double fdim( double, double ); 8120 8256 long double fdim( long double, long double ); 8121 8257 8122 float nan( const char * ); $\indexc{nan}$8258 float nan( const char * );§\indexc{nan}§ 8123 8259 double nan( const char * ); 8124 8260 long double nan( const char * ); … … 8130 8266 \leavevmode 8131 8267 \begin{cfa}[aboveskip=0pt,belowskip=0pt] 8132 float exp( float ); $\indexc{exp}$8268 float exp( float );§\indexc{exp}§ 8133 8269 double exp( double ); 8134 8270 long double exp( long double ); … … 8137 8273 long double _Complex exp( long double _Complex ); 8138 8274 8139 float exp2( float ); $\indexc{exp2}$8275 float exp2( float );§\indexc{exp2}§ 8140 8276 double exp2( double ); 8141 8277 long double exp2( long double ); … … 8144 8280 // long double _Complex exp2( long double _Complex ); 8145 8281 8146 float expm1( float ); $\indexc{expm1}$8282 float expm1( float );§\indexc{expm1}§ 8147 8283 double expm1( double ); 8148 8284 long double expm1( long double ); 8149 8285 8150 float pow( float, float ); $\indexc{pow}$8286 float pow( float, float );§\indexc{pow}§ 8151 8287 double pow( double, double ); 8152 8288 long double pow( long double, long double ); … … 8161 8297 \leavevmode 8162 8298 \begin{cfa}[aboveskip=0pt,belowskip=0pt] 8163 float log( float ); $\indexc{log}$8299 float log( float );§\indexc{log}§ 8164 8300 double log( double ); 8165 8301 long double log( long double ); … … 8168 8304 long double _Complex log( long double _Complex ); 8169 8305 8170 int log2( unsigned int ); $\indexc{log2}$8306 int log2( unsigned int );§\indexc{log2}§ 8171 8307 long int log2( unsigned long int ); 8172 8308 long long int log2( unsigned long long int ) … … 8178 8314 // long double _Complex log2( long double _Complex ); 8179 8315 8180 float log10( float ); $\indexc{log10}$8316 float log10( float );§\indexc{log10}§ 8181 8317 double log10( double ); 8182 8318 long double log10( long double ); … … 8185 8321 // long double _Complex log10( long double _Complex ); 8186 8322 8187 float log1p( float ); $\indexc{log1p}$8323 float log1p( float );§\indexc{log1p}§ 8188 8324 double log1p( double ); 8189 8325 long double log1p( long double ); 8190 8326 8191 int ilogb( float ); $\indexc{ilogb}$8327 int ilogb( float );§\indexc{ilogb}§ 8192 8328 int ilogb( double ); 8193 8329 int ilogb( long double ); 8194 8330 8195 float logb( float ); $\indexc{logb}$8331 float logb( float );§\indexc{logb}§ 8196 8332 double logb( double ); 8197 8333 long double logb( long double ); 8198 8334 8199 float sqrt( float ); $\indexc{sqrt}$8335 float sqrt( float );§\indexc{sqrt}§ 8200 8336 double sqrt( double ); 8201 8337 long double sqrt( long double ); … … 8204 8340 long double _Complex sqrt( long double _Complex ); 8205 8341 8206 float cbrt( float ); $\indexc{cbrt}$8342 float cbrt( float );§\indexc{cbrt}§ 8207 8343 double cbrt( double ); 8208 8344 long double cbrt( long double ); 8209 8345 8210 float hypot( float, float ); $\indexc{hypot}$8346 float hypot( float, float );§\indexc{hypot}§ 8211 8347 double hypot( double, double ); 8212 8348 long double hypot( long double, long double ); … … 8218 8354 \leavevmode 8219 8355 \begin{cfa}[aboveskip=0pt,belowskip=0pt] 8220 float sin( float ); $\indexc{sin}$8356 float sin( float );§\indexc{sin}§ 8221 8357 double sin( double ); 8222 8358 long double sin( long double ); … … 8225 8361 long double _Complex sin( long double _Complex ); 8226 8362 8227 float cos( float ); $\indexc{cos}$8363 float cos( float );§\indexc{cos}§ 8228 8364 double cos( double ); 8229 8365 long double cos( long double ); … … 8232 8368 long double _Complex cos( long double _Complex ); 8233 8369 8234 float tan( float ); $\indexc{tan}$8370 float tan( float );§\indexc{tan}§ 8235 8371 double tan( double ); 8236 8372 long double tan( long double ); … … 8239 8375 long double _Complex tan( long double _Complex ); 8240 8376 8241 float asin( float ); $\indexc{asin}$8377 float asin( float );§\indexc{asin}§ 8242 8378 double asin( double ); 8243 8379 long double asin( long double ); … … 8246 8382 long double _Complex asin( long double _Complex ); 8247 8383 8248 float acos( float ); $\indexc{acos}$8384 float acos( float );§\indexc{acos}§ 8249 8385 double acos( double ); 8250 8386 long double acos( long double ); … … 8253 8389 long double _Complex acos( long double _Complex ); 8254 8390 8255 float atan( float ); $\indexc{atan}$8391 float atan( float );§\indexc{atan}§ 8256 8392 double atan( double ); 8257 8393 long double atan( long double ); … … 8260 8396 long double _Complex atan( long double _Complex ); 8261 8397 8262 float atan2( float, float ); $\indexc{atan2}$8398 float atan2( float, float );§\indexc{atan2}§ 8263 8399 double atan2( double, double ); 8264 8400 long double atan2( long double, long double ); 8265 8401 8266 8402 float atan( float, float ); §\C{// alternative name for atan2}§ 8267 double atan( double, double ); $\indexc{atan}$8403 double atan( double, double );§\indexc{atan}§ 8268 8404 long double atan( long double, long double ); 8269 8405 \end{cfa} … … 8274 8410 \leavevmode 8275 8411 \begin{cfa}[aboveskip=0pt,belowskip=0pt] 8276 float sinh( float ); $\indexc{sinh}$8412 float sinh( float );§\indexc{sinh}§ 8277 8413 double sinh( double ); 8278 8414 long double sinh( long double ); … … 8281 8417 long double _Complex sinh( long double _Complex ); 8282 8418 8283 float cosh( float ); $\indexc{cosh}$8419 float cosh( float );§\indexc{cosh}§ 8284 8420 double cosh( double ); 8285 8421 long double cosh( long double ); … … 8288 8424 long double _Complex cosh( long double _Complex ); 8289 8425 8290 float tanh( float ); $\indexc{tanh}$8426 float tanh( float );§\indexc{tanh}§ 8291 8427 double tanh( double ); 8292 8428 long double tanh( long double ); … … 8295 8431 long double _Complex tanh( long double _Complex ); 8296 8432 8297 float asinh( float ); $\indexc{asinh}$8433 float asinh( float );§\indexc{asinh}§ 8298 8434 double asinh( double ); 8299 8435 long double asinh( long double ); … … 8302 8438 long double _Complex asinh( long double _Complex ); 8303 8439 8304 float acosh( float ); $\indexc{acosh}$8440 float acosh( float );§\indexc{acosh}§ 8305 8441 double acosh( double ); 8306 8442 long double acosh( long double ); … … 8309 8445 long double _Complex acosh( long double _Complex ); 8310 8446 8311 float atanh( float ); $\indexc{atanh}$8447 float atanh( float );§\indexc{atanh}§ 8312 8448 double atanh( double ); 8313 8449 long double atanh( long double ); … … 8322 8458 \leavevmode 8323 8459 \begin{cfa}[aboveskip=0pt,belowskip=0pt] 8324 float erf( float ); $\indexc{erf}$8460 float erf( float );§\indexc{erf}§ 8325 8461 double erf( double ); 8326 8462 long double erf( long double ); … … 8329 8465 long double _Complex erf( long double _Complex ); 8330 8466 8331 float erfc( float ); $\indexc{erfc}$8467 float erfc( float );§\indexc{erfc}§ 8332 8468 double erfc( double ); 8333 8469 long double erfc( long double ); … … 8336 8472 long double _Complex erfc( long double _Complex ); 8337 8473 8338 float lgamma( float ); $\indexc{lgamma}$8474 float lgamma( float );§\indexc{lgamma}§ 8339 8475 double lgamma( double ); 8340 8476 long double lgamma( long double ); … … 8343 8479 long double lgamma( long double, int * ); 8344 8480 8345 float tgamma( float ); $\indexc{tgamma}$8481 float tgamma( float );§\indexc{tgamma}§ 8346 8482 double tgamma( double ); 8347 8483 long double tgamma( long double ); … … 8389 8525 unsigned long long int ceiling( unsigned long long int n, unsigned long long int align ); 8390 8526 8391 float floor( float ); $\indexc{floor}$8527 float floor( float );§\indexc{floor}§ 8392 8528 double floor( double ); 8393 8529 long double floor( long double ); 8394 8530 8395 float ceil( float ); $\indexc{ceil}$8531 float ceil( float );§\indexc{ceil}§ 8396 8532 double ceil( double ); 8397 8533 long double ceil( long double ); 8398 8534 8399 float trunc( float ); $\indexc{trunc}$8535 float trunc( float );§\indexc{trunc}§ 8400 8536 double trunc( double ); 8401 8537 long double trunc( long double ); 8402 8538 8403 float rint( float ); $\indexc{rint}$8539 float rint( float );§\indexc{rint}§ 8404 8540 long double rint( long double ); 8405 8541 long int rint( float ); … … 8410 8546 long long int rint( long double ); 8411 8547 8412 long int lrint( float ); $\indexc{lrint}$8548 long int lrint( float );§\indexc{lrint}§ 8413 8549 long int lrint( double ); 8414 8550 long int lrint( long double ); … … 8417 8553 long long int llrint( long double ); 8418 8554 8419 float nearbyint( float ); $\indexc{nearbyint}$8555 float nearbyint( float );§\indexc{nearbyint}§ 8420 8556 double nearbyint( double ); 8421 8557 long double nearbyint( long double ); 8422 8558 8423 float round( float ); $\indexc{round}$8559 float round( float );§\indexc{round}§ 8424 8560 long double round( long double ); 8425 8561 long int round( float ); … … 8430 8566 long long int round( long double ); 8431 8567 8432 long int lround( float ); $\indexc{lround}$8568 long int lround( float );§\indexc{lround}§ 8433 8569 long int lround( double ); 8434 8570 long int lround( long double ); … … 8443 8579 \leavevmode 8444 8580 \begin{cfa}[aboveskip=0pt,belowskip=0pt] 8445 float copysign( float, float ); $\indexc{copysign}$8581 float copysign( float, float );§\indexc{copysign}§ 8446 8582 double copysign( double, double ); 8447 8583 long double copysign( long double, long double ); 8448 8584 8449 float frexp( float, int * ); $\indexc{frexp}$8585 float frexp( float, int * );§\indexc{frexp}§ 8450 8586 double frexp( double, int * ); 8451 8587 long double frexp( long double, int * ); 8452 8588 8453 float ldexp( float, int ); $\indexc{ldexp}$8589 float ldexp( float, int );§\indexc{ldexp}§ 8454 8590 double ldexp( double, int ); 8455 8591 long double ldexp( long double, int ); 8456 8592 8457 [ float, float ] modf( float ); $\indexc{modf}$8593 [ float, float ] modf( float );§\indexc{modf}§ 8458 8594 float modf( float, float * ); 8459 8595 [ double, double ] modf( double ); … … 8462 8598 long double modf( long double, long double * ); 8463 8599 8464 float nextafter( float, float ); $\indexc{nextafter}$8600 float nextafter( float, float );§\indexc{nextafter}§ 8465 8601 double nextafter( double, double ); 8466 8602 long double nextafter( long double, long double ); 8467 8603 8468 float nexttoward( float, long double ); $\indexc{nexttoward}$8604 float nexttoward( float, long double );§\indexc{nexttoward}§ 8469 8605 double nexttoward( double, long double ); 8470 8606 long double nexttoward( long double, long double ); 8471 8607 8472 float scalbn( float, int ); $\indexc{scalbn}$8608 float scalbn( float, int );§\indexc{scalbn}§ 8473 8609 double scalbn( double, int ); 8474 8610 long double scalbn( long double, int ); 8475 8611 8476 float scalbln( float, long int ); $\indexc{scalbln}$8612 float scalbln( float, long int );§\indexc{scalbln}§ 8477 8613 double scalbln( double, long int ); 8478 8614 long double scalbln( long double, long int ); … … 8734 8870 All \newterm{pseudo random-number generators} (\newterm{PRNG}) involve some technique to scramble bits of a value, \eg multiplicative recurrence: 8735 8871 \begin{cfa} 8736 rand = 3 6973 * (rand & 65535) + (rand >> 16); // scramble bits8872 rand = 33967 * (rand + 1063); // scramble bits 8737 8873 \end{cfa} 8738 8874 Multiplication of large values adds new least-significant bits and drops most-significant bits. … … 8741 8877 bits 63--32 (most) & bits 31--0 (least) \\ 8742 8878 \hline 8743 0x0 & 0x3e8e36\\8744 0x5f & 0x718c25e1\\8745 0xad3e & 0x7b5f1dbe\\8746 0xbc3b & 0xac69ff19\\8747 0x1070f & 0x2d258dc6 \\ 8879 ©0x0© & ©0x3e8e36© \\ 8880 ©0x5f© & ©0x718c25e1© \\ 8881 ©0xad3e© & ©0x7b5f1dbe© \\ 8882 ©0xbc3b© & ©0xac69ff19© \\ 8883 ©0x1070f© & ©0x2d258dc6© 8748 8884 \end{tabular} 8749 8885 \end{quote} … … 8751 8887 The least-significant bits \emph{appear} random but the same bits are always generated given a fixed starting value, called the \newterm{seed} (value 0x3e8e36 above). 8752 8888 Hence, if a program uses the same seed, the same sequence of pseudo-random values is generated from the PRNG. 8753 Often the seed is set to another random value like a program's process identifier ( ©getpid©\index{getpid@©getpid©}) or time when the program is run;8889 Often the seed is set to another random value like a program's process identifier (\Indexc{getpid}) or time when the program is run; 8754 8890 hence, one random value bootstraps another. 8755 8891 Finally, a PRNG usually generates a range of large values, \eg ©[0, UINT_MAX]©, which are scaled using the modulus operator, \eg ©prng() % 5© produces random values in the range 0--4. 8756 8892 8757 \CFA provides a sequential PRNG type only accessible by a single thread (not thread-safe) and a set of global and companion thread PRNG functions accessible by multiple threads without contention. 8893 \CFA provides 32/64-bit sequential PRNG type only accessible by a single thread (not thread-safe) and a set of global routines and companion thread PRNG functions accessible by multiple threads without contention. 8894 To use the PRNG interface \Textbf{requires including \Indexc{stdlib.hfa}}. 8758 8895 \begin{itemize} 8759 8896 \item 8760 The ©PRNG© type is for sequential programs, like coroutining: 8761 \begin{cfa} 8762 struct PRNG { ... }; $\C[3.75in]{// opaque type}$ 8763 void ?{}( PRNG & prng ); §\C{// random seed}§ 8764 void ?{}( PRNG & prng, uint32_t seed ); §\C{// fixed seed}§ 8765 void set_seed( PRNG & prng, uint32_t seed ); §\C{// set seed}§ 8766 uint32_t get_seed( PRNG & prng ); §\C{// get seed}§ 8767 uint32_t prng( PRNG & prng ); §\C{// [0,UINT\_MAX]}§ 8768 uint32_t prng( PRNG & prng, uint32_t u ); §\C{// [0,u)}§ 8769 uint32_t prng( PRNG & prng, uint32_t l, uint32_t u ); §\C{// [l,u]}§ 8770 uint32_t calls( PRNG & prng ); §\C{// number of calls}\CRT§ 8771 \end{cfa} 8897 The ©PRNG© types for sequential programs, including coroutining, are: 8898 \begin{cfa} 8899 struct PRNG32 {}; §\C{// opaque type, no copy or assignment}§ 8900 void ?{}( PRNG32 & prng, uint32_t seed ); §\C{// fixed seed}§ 8901 void ?{}( PRNG32 & prng ); §\C{// random seed}§ 8902 void set_seed( PRNG32 & prng, uint32_t seed ); §\C{// set seed}§ 8903 uint32_t get_seed( PRNG32 & prng ); §\C{// get seed}§ 8904 uint32_t prng( PRNG32 & prng ); §\C{// [0,UINT\_MAX]}§ 8905 uint32_t prng( PRNG32 & prng, uint32_t u ); §\C{// [0,u)}§ 8906 uint32_t prng( PRNG32 & prng, uint32_t l, uint32_t u ); §\C{// [l,u]}§ 8907 uint32_t calls( PRNG32 & prng ); §\C{// number of calls}§ 8908 void copy( PRNG32 & dst, PRNG32 & src ); §\C{// checkpoint PRNG state}§ 8909 \end{cfa} 8910 \begin{cfa} 8911 struct PRNG64 {}; §\C{// opaque type, no copy or assignment}§ 8912 void ?{}( PRNG64 & prng, uint64_t seed ); §\C{// fixed seed}§ 8913 void ?{}( PRNG64 & prng ); §\C{// random seed}§ 8914 void set_seed( PRNG64 & prng, uint64_t seed ); §\C{// set seed}§ 8915 uint64_t get_seed( PRNG64 & prng ); §\C{// get seed}§ 8916 uint64_t prng( PRNG64 & prng ); §\C{// [0,UINT\_MAX]}§ 8917 uint64_t prng( PRNG64 & prng, uint64_t u ); §\C{// [0,u)}§ 8918 uint64_t prng( PRNG64 & prng, uint64_t l, uint64_t u ); §\C{// [l,u]}§ 8919 uint64_t calls( PRNG64 & prng ); §\C{// number of calls}§ 8920 void copy( PRNG64 & dst, PRNG64 & src ); §\C{// checkpoint PRNG state}§ 8921 \end{cfa} 8922 The type ©PRNG© is aliased to ©PRNG64© on 64-bit architectures and ©PRNG32© on 32-bit architectures. 8772 8923 A ©PRNG© object is used to randomize behaviour or values during execution, \eg in games, a character makes a random move or an object takes on a random value. 8773 8924 In this scenario, it is useful to have multiple ©PRNG© objects, \eg one per player or object. 8774 However, sequential execution is still repeatable given the same starting seeds for all ©PRNG©s. 8925 However, sequential execution is still repeatable given the same starting seeds for all ©PRNG©s. 8775 8926 \VRef[Figure]{f:SequentialPRNG} shows an example that creates two sequential ©PRNG©s, sets both to the same seed (1009), and illustrates the three forms for generating random values, where both ©PRNG©s generate the same sequence of values. 8927 Note, to prevent accidental PRNG copying, the copy constructor and assignment are hidden. 8928 To copy a PRNG for checkpointing, use the explicit ©copy© member. 8776 8929 8777 8930 \begin{figure} 8778 8931 \begin{cfa} 8779 PRNG prng1, prng2;8780 ®set_seed( prng1, 1009 )®; ®set_seed(prng2, 1009 )®;8932 PRNG sprng1, sprng2; §\C{// select appropriate 32/64-bit PRNG}§ 8933 ®set_seed( sprng1, 1009 )®; ®set_seed( sprng2, 1009 )®; 8781 8934 for ( 10 ) { 8782 8935 // Do not cascade prng calls because side-effect functions called in arbitrary order. 8783 sout | nlOff | ®prng( prng1 )®; sout | ®prng( prng1, 5 )®; sout | ®prng(prng1, 0, 5 )® | '\t';8784 sout | ®prng( prng2 )®; sout | ®prng( prng2, 5 )®; sout | ®prng(prng2, 0, 5 )® | nlOn;8936 sout | nlOff | ®prng( sprng1 )®; sout | ®prng( sprng1, 5 )®; sout | ®prng( sprng1, 0, 5 )® | '\t'; 8937 sout | ®prng( sprng2 )®; sout | ®prng( sprng2, 5 )®; sout | ®prng( sprng2, 0, 5 )® | nlOn; 8785 8938 } 8786 8939 \end{cfa} … … 8821 8974 The PRNG global and companion thread functions are for concurrent programming, such as randomizing execution in short-running programs, \eg ©yield( prng() % 5 )©. 8822 8975 \begin{cfa} 8823 void set_seed( uint32_t seed ); $\C[3.75in]{// set global seed}$8824 uint32_t get_seed();§\C{// get global seed}§8825 // SLOWER 8826 uint32_t prng();§\C{// [0,UINT\_MAX]}§8827 uint32_t prng( uint32_t u );§\C{// [0,u)}§8828 uint32_t prng( uint32_t l, uint32_t u );§\C{// [l,u]}§8829 // FASTER 8830 uint32_t prng( $thread\LstStringStyle{\textdollar}$& th ); §\C{// [0,UINT\_MAX]}§8831 uint32_t prng( $thread\LstStringStyle{\textdollar}$ & th, uint32_t u ); §\C{// [0,u)}§8832 uint32_t prng( $thread\LstStringStyle{\textdollar}$ & th, uint32_t l, uint32_t u ); §\C{// [l,u]}\CRT§8976 void set_seed( size_t seed ); §\C{// set global seed}§ 8977 size_t get_seed(); §\C{// get global seed}§ 8978 // SLOWER, global routines 8979 size_t prng( void ); §\C{// [0,UINT\_MAX]}§ 8980 size_t prng( size_t u ); §\C{// [0,u)}§ 8981 size_t prng( size_t l, size_t u ); §\C{// [l,u]}§ 8982 // FASTER, thread members 8983 size_t prng( §thread\LstStringStyle{\textdollar}§ & th ); §\C{// [0,UINT\_MAX]}§ 8984 size_t prng( §thread\LstStringStyle{\textdollar}§ & th, size_t u ); §\C{// [0,u)}§ 8985 size_t prng( §thread\LstStringStyle{\textdollar}§ & th, size_t l, size_t u ); §\C{// [l,u]}§ 8833 8986 \end{cfa} 8834 8987 The only difference between the two sets of ©prng© routines is performance. … … 8841 8994 Hence, these threads generate different sequences of random numbers. 8842 8995 If each thread needs its own seed, use a sequential ©PRNG© in each thread. 8843 The slower ©prng© functions \emph{without} a thread argument call ©active_thread© internally to indirectly access the current thread's PRNG state, while the faster ©prng© functions \emph{with} a thread argumentdirectly access the thread through the thread parameter.8996 The slower ©prng© global functions, \ie \emph{without} a thread argument, call ©active_thread© internally to indirectly access the current thread's PRNG state, while the faster ©prng© functions, \ie \emph{with} a thread argument, directly access the thread through the thread parameter. 8844 8997 If a thread pointer is available, \eg in thread main, eliminating the call to ©active_thread© significantly reduces the cost of accessing the thread's PRNG state. 8845 8998 \VRef[Figure]{f:ConcurrentPRNG} shows an example using the slower/faster concurrent PRNG in the program main and a thread. … … 8856 9009 int main() { 8857 9010 set_seed( 1009 ); 8858 $\R{thread\LstStringStyle{\textdollar}}$®& th = *active_thread()®; // program-main thread-address9011 §\R{thread\LstStringStyle{\textdollar}}§ ®& th = *active_thread()®; // program-main thread-address 8859 9012 for ( i; 10 ) { 8860 9013 sout | nlOff | ®prng()®; sout | ®prng( 5 )®; sout | ®prng( 0, 5 )® | '\t'; // SLOWER … … 9079 9232 \hline 9080 9233 \begin{cfa} 9081 #include <gmp.h> $\indexc{gmp.h}$9234 #include <gmp.h>§\indexc{gmp.h}§ 9082 9235 int main( void ) { 9083 9236 ®gmp_printf®( "Factorial Numbers\n" ); … … 9093 9246 & 9094 9247 \begin{cfa} 9095 #include <gmp.hfa> $\indexc{gmp}$9248 #include <gmp.hfa>§\indexc{gmp}§ 9096 9249 int main( void ) { 9097 9250 sout | "Factorial Numbers"; … … 9165 9318 \begin{cfa}[belowskip=0pt] 9166 9319 // implementation 9167 struct Rational { $\indexc{Rational}$9320 struct Rational {§\indexc{Rational}§ 9168 9321 long int numerator, denominator; §\C{// invariant: denominator > 0}§ 9169 9322 }; // Rational -
libcfa/src/collections/string_res.cfa
rc75b30a r32490deb 10 10 // Created On : Fri Sep 03 11:00:00 2021 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Tue Jan 16 22:19:27202413 // Update Count : 3512 // Last Modified On : Mon Jan 22 23:12:42 2024 13 // Update Count : 43 14 14 // 15 15 … … 263 263 bool cont = false; 264 264 265 _Istream_C strcf = { cstr, (_Istream_str_base)f };265 _Istream_Cwidth cf = { cstr, (_Istream_str_base)f }; 266 266 if ( ! cf.flags.rwd ) cf.wd = wd; 267 267 -
libcfa/src/fstream.cfa
rc75b30a r32490deb 10 10 // Created On : Wed May 27 17:56:53 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Wed Nov 15 10:51:14 202313 // Update Count : 55 212 // Last Modified On : Sun Jan 28 09:56:08 2024 13 // Update Count : 554 14 14 // 15 15 … … 209 209 void ?{}( ifstream & is, void * file ) with( is ) { 210 210 file$ = file; 211 nlOnOff$ = false; 211 nlOnOff$ = false; // => skip newlines when reading single characters 212 212 } // ?{} 213 213 -
libcfa/src/iostream.cfa
rc75b30a r32490deb 10 10 // Created On : Wed May 27 17:56:53 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Wed Jan 3 10:53:13202413 // Update Count : 1 89812 // Last Modified On : Sun Jan 28 11:58:54 2024 13 // Update Count : 1917 14 14 // 15 15 … … 944 944 istype & nl( istype & is ) { 945 945 fmt( is, "%*[^\n]" ); // ignore characters to newline 946 if ( ! eof( is ) && getANL$( is ) ) fmt( is, "%*c" );// read newline946 if ( ! eof( is ) ) fmt( is, "%*c" ); // read newline 947 947 return is; 948 948 } // nl … … 984 984 } 985 985 986 istype & ?|?( istype & is, _Istream_Cquoted f ) with( f ) { 987 char fmtstr[32]; // storage scanset and format codes 986 istype & ?|?( istype & is, _Istream_Cquoted f ) with( f.cstr ) { 987 int args; 988 fini: { 989 args = fmt( is, "%*[ \f\n\r\t\v]" ); // remove leading whitespace 990 if ( eof( is ) ) break fini; 991 char rfmt[4] = { delimiters[0], '%', 'n', '\0' }; 992 int len = 0; // may not be set in fmt 993 args = fmt( is, rfmt, &len ); // remove leading quote 994 if ( len == 0 || eof( is ) ) break fini; 995 996 // Change the remainder of the read into a getline by reseting the closing delimiter. 997 if ( delimiters[1] != '\0' ) { 998 delimiters[0] = delimiters[1]; 999 delimiters[1] = '\0'; 1000 } // if 1001 flags.delimiter = true; 1002 return is | *(_Istream_Cstr *)&f; 1003 } // fini 1004 // read failed => no pattern match => set string to null 1005 if ( ! flags.ignore && s != 0p && args == 0 ) s[0] = '\0'; 1006 if ( args == 1 && eof( is ) ) { // data but scan ended at EOF 1007 clear( is ); // => reset EOF => detect again on next read 1008 } // if 1009 return is; 1010 } 1011 1012 istype & ?|?( istype & is, _Istream_Cstr f ) with( f.cstr ) { 1013 const char * scanset; 1014 size_t nscanset = 0; 1015 if ( flags.delimiter ) scanset = delimiters; // getline ? 1016 else scanset = f.cstr.scanset; 1017 if ( scanset ) nscanset = strlen( scanset ); 1018 1019 char fmtstr[nscanset + 32]; // storage for scanset and format codes 988 1020 fmtstr[0] = '%'; 989 990 1021 int pos = 1; 991 1022 int args; 992 1023 bool check = true; 993 1024 994 if ( cstr.flags.ignore ) { check = false; fmtstr[1] = '*'; pos += 1; }995 int rwd = cstr.wd;996 if ( cstr.wd != -1 ) {// => just ignore versus ignore with width1025 if ( flags.ignore ) { check = false; fmtstr[1] = '*'; pos += 1; } 1026 int rwd = wd; 1027 if ( wd != -1 ) { // => just ignore versus ignore with width 997 1028 // wd is buffer bytes available (for input chars + null terminator) 998 1029 // rwd is count of input chars 999 1030 // no maximum width necessary because text ignored => width is read width 1000 if ( cstr.flags.rwd ) check = false; 1001 else rwd = cstr.wd - 1; 1031 if ( flags.rwd ) check = false; 1032 else rwd = wd - 1; 1033 assert( rwd > 0 ); 1002 1034 pos += sprintf( &fmtstr[pos], "%d", rwd ); 1003 1035 } // if 1004 1036 1005 int len = 0; // may not be set in fmt1006 char enddelim;1007 if ( ! cstr.flags.inex ) { // => quoted getline1008 args = fmt( is, "%*[ \f\n\r\t\v]" ); // remove leading whitespace1009 if ( eof( is ) ) goto Eof;1010 char rfmt[4] = { cstr.delimiters[0], '%', 'n', '\0' };1011 args = fmt( is, rfmt, &len ); // remove leading quote1012 if ( len == 0 || eof( is ) ) goto Eof;1013 } // if1014 enddelim = cstr.delimiters[1] == '\0' ? cstr.delimiters[0] : cstr.delimiters[1];1015 sprintf( &fmtstr[pos], "[^%c]%%n", enddelim );1016 if ( cstr.flags.ignore ) args = fmt( is, fmtstr, &len ); // no string argument for '*'1017 else args = fmt( is, fmtstr, cstr.s, &len );1018 if ( check && len == rwd && ! eof( is ) ) { // might not fit1019 char peek;1020 fmt( is, "%c", &peek ); // check for delimiter1021 if ( ! eof( is ) ) {1022 if ( peek != enddelim ) {1023 ungetc( is, peek );1024 throwResume ExceptionInst( cstring_length );1025 } // if1026 } // if1027 } else fmt( is, "%*c" ); // remove delimiter1028 Eof: ;1029 if ( rwd > 0 && args == 0 ) cstr.s[0] = '\0'; // read failed => no pattern match => set string to null1030 if ( args == 1 && eof( is ) ) { // data but scan ended at EOF1031 clear( is ); // => reset EOF => detect again on next read1032 } // if1033 return is;1034 }1035 1036 istype & ?|?( istype & is, _Istream_Cstr f ) with( f ) {1037 const char * scanset;1038 size_t nscanset = 0;1039 if ( flags.delimiter ) scanset = delimiters; // getline ?1040 else scanset = f.scanset;1041 if ( scanset ) nscanset = strlen( scanset );1042 1043 char fmtstr[nscanset + 32]; // storage for scanset and format codes1044 fmtstr[0] = '%';1045 1046 int pos = 1;1047 int args;1048 bool check = true;1049 1050 if ( f.flags.ignore ) { check = false; fmtstr[1] = '*'; pos += 1; }1051 int rwd = f.wd;1052 if ( f.wd != -1 ) { // => just ignore versus ignore with width1053 // wd is buffer bytes available (for input chars + null terminator)1054 // rwd is count of input chars1055 // no maximum width necessary because text ignored => width is read width1056 if ( f.flags.rwd ) check = false;1057 else rwd = f.wd - 1;1058 pos += sprintf( &fmtstr[pos], "%d", rwd );1059 } // if1060 1061 1037 if ( ! scanset ) { // %s, %*s, %ws, %*ws 1062 // fprintf( stderr, "cstr %s\n", f.s );1038 // fprintf( stderr, "cstr %s\n", s ); 1063 1039 strcpy( &fmtstr[pos], "s%n" ); 1064 1040 int len = 0; // may not be set in fmt 1065 if ( f .flags.ignore ) args = fmt( is, fmtstr, &len ); // no string argument for '*'1066 else args = fmt( is, fmtstr, f.s, &len );1067 // fprintf( stderr, "cstr %s %d %d %d %s\n", fmtstr, args, len, f.wd, f.s );1041 if ( flags.ignore ) args = fmt( is, fmtstr, &len ); // no string argument for '*' 1042 else args = fmt( is, fmtstr, s, &len ); 1043 // fprintf( stderr, "cstr %s %d %d %d %s\n", fmtstr, args, len, wd, s ); 1068 1044 if ( check && len >= rwd && ! eof( is ) ) { // might not fit 1069 1045 char peek; … … 1076 1052 } // if 1077 1053 // FIX ME: CFA strings need to be modified to NOT change the argument for this case, then this can be removed. 1078 if ( rwd > 0 && args == 0 ) f.s[0]= '\0';// read failed => no pattern match => set string to null1054 if ( ! flags.ignore && args == 0 ) s[0]= '\0'; // read failed => no pattern match => set string to null 1079 1055 } else { 1080 if ( f .flags.delimiter ) { // getline1056 if ( flags.delimiter ) { // getline 1081 1057 int len = 0; // may not be set in fmt 1082 sprintf( &fmtstr[pos], "[^%c]%%n", f.delimiters[0] ); 1083 if ( f.flags.ignore ) args = fmt( is, fmtstr, &len ); // no string argument for '*' 1084 else args = fmt( is, fmtstr, f.s, &len ); 1058 if ( delimiters[2] != '\0' ) { // read single character ? 1059 sprintf( &fmtstr[pos], "c%%n" ); 1060 } else { 1061 sprintf( &fmtstr[pos], "[^%c]%%n", delimiters[0] ); 1062 } // if 1063 if ( flags.ignore ) args = fmt( is, fmtstr, &len ); // no string argument for '*' 1064 else args = fmt( is, fmtstr, s, &len ); 1085 1065 if ( check && len == rwd && ! eof( is ) ) { // might not fit 1086 fmtstr[0] = f.delimiters[0]; fmtstr[1] = '%'; fmtstr[2] = 'n'; fmtstr[3] = '\0';1087 fmt( is, fmtstr, &len ); // removedelimiter1066 char peek; 1067 fmt( is, "%c", &peek ); // check for delimiter 1088 1068 if ( ! eof( is ) ) { 1089 // if ( peek != f.delimiter[0] ) { 1090 if ( len != 1 ) { 1091 // ungetc( is, peek ); 1069 if ( peek != delimiters[0] ) { 1070 ungetc( is, peek ); 1092 1071 throwResume ExceptionInst( cstring_length ); 1093 1072 } // if … … 1097 1076 // incl %[xxx], %*[xxx], %w[xxx], %*w[xxx] 1098 1077 // excl %[^xxx], %*[^xxx], %w[^xxx], %*w[^xxx] 1099 sprintf( &fmtstr[pos], "[%s%s]%%n", f .flags.inex ? "^" : "", scanset );1100 // fprintf( stderr, "incl/excl %s %d\n", fmtstr, f.wd );1078 sprintf( &fmtstr[pos], "[%s%s]%%n", flags.inex ? "^" : "", scanset ); 1079 // fprintf( stderr, "incl/excl %s %d\n", fmtstr, wd ); 1101 1080 int len = 0; // may not be set in fmt 1102 if ( f .flags.ignore ) args = fmt( is, fmtstr, &len ); // no string argument for '*'1103 else args = fmt( is, fmtstr, f.s, &len );1104 // fprintf( stderr, "incl/excl %s \"%s\" %d %d %d %d %d %c\n", fmtstr, f.s, args, f.wd, len, eof( is ), check, f.s[f.wd] );1081 if ( flags.ignore ) args = fmt( is, fmtstr, &len ); // no string argument for '*' 1082 else args = fmt( is, fmtstr, s, &len ); 1083 // fprintf( stderr, "incl/excl %s \"%s\" %d %d %d %d %d %c\n", fmtstr, s, args, wd, len, eof( is ), check, s[wd] ); 1105 1084 if ( check && len == rwd && ! eof( is ) ) { // might not fit 1106 1085 // fprintf( stderr, "overflow\n" ); … … 1110 1089 if ( ! eof( is ) ) { 1111 1090 ungetc( is, peek ); 1112 if ( f .flags.inex ^ strchr( f.scanset, peek ) != 0p ) throwResume ExceptionInst( cstring_length );1091 if ( flags.inex ^ strchr( scanset, peek ) != 0p ) throwResume ExceptionInst( cstring_length ); 1113 1092 } // if 1114 1093 } // if 1115 1094 } // if 1116 if ( rwd > 0 && args == 0 ) f.s[0]= '\0';// read failed => no pattern match => set string to null1095 if ( ! flags.ignore && args == 0 ) s[0]= '\0'; // read failed => no pattern match => set string to null 1117 1096 } // if 1118 1097 if ( args == 1 && eof( is ) ) { // data but scan ended at EOF … … 1120 1099 clear( is ); // => reset EOF => detect again on next read 1121 1100 } // if 1122 return is;1123 } // ?|?1124 1125 istype & ?|?( istype & is, _Istream_Char f ) {1126 fmt( is, "%*c" ); // argument variable unused1127 1101 return is; 1128 1102 } // ?|? … … 1145 1119 } // distribution 1146 1120 1121 INPUT_FMT_IMPL( char, "c" ) 1147 1122 INPUT_FMT_IMPL( signed char, "hhi" ) 1148 1123 INPUT_FMT_IMPL( unsigned char, "hhi" ) -
libcfa/src/iostream.hfa
rc75b30a r32490deb 10 10 // Created On : Wed May 27 17:56:53 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Wed Jan 3 10:53:18202413 // Update Count : 61012 // Last Modified On : Sun Jan 28 11:56:29 2024 13 // Update Count : 733 14 14 // 15 15 … … 196 196 // *********************************** integral *********************************** 197 197 198 // See 6.7.9. 19) The initialization shall occur in initializer list order, each initializer provided for a particular199 // subobject overriding any previously listed initializer for the same subobject; ***all subobjects that are not200 // initialized explicitly shall be initialized implicitly the same as objects that have static storage duration.***201 202 198 #define INTEGRAL_FMT_DECL( T, CODE ) \ 203 199 static inline { \ 204 _Ostream_Manip(T) bin( T val ) { return (_Ostream_Manip(T))@{ val, 1, 0,'b', { .all : 0 } }; } \205 _Ostream_Manip(T) oct( T val ) { return (_Ostream_Manip(T))@{ val, 1, 0,'o', { .all : 0 } }; } \206 _Ostream_Manip(T) hex( T val ) { return (_Ostream_Manip(T))@{ val, 1, 0,'x', { .all : 0 } }; } \207 _Ostream_Manip(T) wd( unsigned int w , T val ) { return (_Ostream_Manip(T))@{ val, w, 0,CODE, { .all : 0 } }; } \208 _Ostream_Manip(T) wd( unsigned int w , unsigned int pc, T val ) { return (_Ostream_Manip(T))@{ val, w, pc,CODE, { .flags.pc : true } }; } \209 _Ostream_Manip(T) & wd( unsigned int w , _Ostream_Manip(T) & fmt ) { fmt.wd = w; return fmt; } \210 _Ostream_Manip(T) & wd( unsigned int w , unsigned int pc, _Ostream_Manip(T) & fmt ) { fmt.wd = w; fmt.pc = pc; fmt.flags.pc = true; return fmt; } \200 _Ostream_Manip(T) bin( T val ) { return (_Ostream_Manip(T))@{ .val : val, .wd : 1, .pc : 0, .base : 'b', { .all : 0 } }; } \ 201 _Ostream_Manip(T) oct( T val ) { return (_Ostream_Manip(T))@{ .val : val, .wd : 1, .pc : 0, .base : 'o', { .all : 0 } }; } \ 202 _Ostream_Manip(T) hex( T val ) { return (_Ostream_Manip(T))@{ .val : val, .wd : 1, .pc : 0, .base : 'x', { .all : 0 } }; } \ 203 _Ostream_Manip(T) wd( unsigned int wd, T val ) { return (_Ostream_Manip(T))@{ .val : val, .wd : wd, .pc : 0, .base : CODE, { .all : 0 } }; } \ 204 _Ostream_Manip(T) wd( unsigned int wd, unsigned int pc, T val ) { return (_Ostream_Manip(T))@{ .val : val, .wd : wd, .pc : pc, .base : CODE, { .flags.pc : true } }; } \ 205 _Ostream_Manip(T) & wd( unsigned int wd, _Ostream_Manip(T) & fmt ) { fmt.wd = wd; return fmt; } \ 206 _Ostream_Manip(T) & wd( unsigned int wd, unsigned int pc, _Ostream_Manip(T) & fmt ) { fmt.wd = wd; fmt.pc = pc; fmt.flags.pc = true; return fmt; } \ 211 207 _Ostream_Manip(T) & left( _Ostream_Manip(T) & fmt ) { fmt.flags.left = true; return fmt; } \ 212 208 _Ostream_Manip(T) & upcase( _Ostream_Manip(T) & fmt ) { if ( fmt.base == 'x' || fmt.base == 'b' ) fmt.base -= 32; /* upper case */ return fmt; } \ 213 209 _Ostream_Manip(T) & nobase( _Ostream_Manip(T) & fmt ) { fmt.flags.nobsdp = true; return fmt; } \ 214 210 _Ostream_Manip(T) & pad0( _Ostream_Manip(T) & fmt ) { fmt.flags.pad0 = true; return fmt; } \ 215 _Ostream_Manip(T) sign( T val ) { return (_Ostream_Manip(T))@{ val, 1, 0,CODE, { .flags.sign : true } }; } \211 _Ostream_Manip(T) sign( T val ) { return (_Ostream_Manip(T))@{ .val : val, .wd : 1, .pc : 0, .base : CODE, { .flags.sign : true } }; } \ 216 212 _Ostream_Manip(T) & sign( _Ostream_Manip(T) & fmt ) { fmt.flags.sign = true; return fmt; } \ 217 213 } /* distribution */ \ … … 241 237 #define FLOATING_POINT_FMT_DECL( T ) \ 242 238 static inline { \ 243 _Ostream_Manip(T) hex( T val ) { return (_Ostream_Manip(T))@{ val, 1, 0, 'a', { .all : 0 } }; } \ 244 _Ostream_Manip(T) sci( T val ) { return (_Ostream_Manip(T))@{ val, 1, 0, 'e', { .all : 0 } }; } \ 245 _Ostream_Manip(T) eng( T val ) { return (_Ostream_Manip(T))@{ val, 1, -1, 'g', { .flags.eng : true } }; } \ 246 _Ostream_Manip(T) wd( unsigned int w, T val ) { return (_Ostream_Manip(T))@{ val, w, 0, 'g', { .all : 0 } }; } \ 247 _Ostream_Manip(T) wd( unsigned int w, unsigned int pc, T val ) { return (_Ostream_Manip(T))@{ val, w, pc, 'f', { .flags.pc : true } }; } \ 248 _Ostream_Manip(T) ws( unsigned int w, unsigned int pc, T val ) { return (_Ostream_Manip(T))@{ val, w, pc, 'g', { .flags.pc : true } }; } \ 249 _Ostream_Manip(T) & wd( unsigned int w, _Ostream_Manip(T) & fmt ) { if ( fmt.flags.eng ) fmt.base = 'f'; fmt.wd = w; return fmt; } \ 250 _Ostream_Manip(T) & wd( unsigned int w, unsigned int pc, _Ostream_Manip(T) & fmt ) { if ( fmt.flags.eng ) fmt.base = 'f'; fmt.wd = w; fmt.pc = pc; fmt.flags.pc = true; return fmt; } \ 251 _Ostream_Manip(T) & ws( unsigned int w, unsigned int pc, _Ostream_Manip(T) & fmt ) { fmt.wd = w; fmt.pc = pc; fmt.flags.pc = true; return fmt; } \ 239 _Ostream_Manip(T) hex( T val ) { return (_Ostream_Manip(T))@{ .val : val, .wd : 1, .pc : 0, .base : 'a', { .all : 0 } }; } \ 240 _Ostream_Manip(T) sci( T val ) { return (_Ostream_Manip(T))@{ .val : val, .wd : 1, .pc : 0, .base : 'e', { .all : 0 } }; } \ 241 _Ostream_Manip(T) eng( T val ) { return (_Ostream_Manip(T))@{ .val : val, 1, -1, .base : 'g', { .flags.eng : true } }; } \ 242 _Ostream_Manip(T) wd( unsigned int wd, T val ) { return (_Ostream_Manip(T))@{ .val : val, .wd : wd, .pc : 0, .base : 'g', { .all : 0 } }; } \ 243 _Ostream_Manip(T) wd( unsigned int wd, unsigned int pc, T val ) { return (_Ostream_Manip(T))@{ .val : val, .wd : wd, .pc : pc, .base : 'f', { .flags.pc : true } }; } \ 244 _Ostream_Manip(T) ws( unsigned int wd, unsigned int pc, T val ) { return (_Ostream_Manip(T))@{ .val : val, .wd : wd, .pc : pc, .base : 'g', { .flags.pc : true } }; } \ 245 _Ostream_Manip(T) & wd( unsigned int wd, _Ostream_Manip(T) & fmt ) { if ( fmt.flags.eng ) fmt.base = 'f'; fmt.wd = wd; return fmt; } \ 246 _Ostream_Manip(T) & wd( unsigned int wd, unsigned int pc, _Ostream_Manip(T) & fmt ) { \ 247 if ( fmt.flags.eng ) fmt.base = 'f'; fmt.wd = wd; fmt.pc = pc; fmt.flags.pc = true; return fmt; } \ 248 _Ostream_Manip(T) & ws( unsigned int wd, unsigned int pc, _Ostream_Manip(T) & fmt ) { fmt.wd = wd; fmt.pc = pc; fmt.flags.pc = true; return fmt; } \ 252 249 _Ostream_Manip(T) & left( _Ostream_Manip(T) & fmt ) { fmt.flags.left = true; return fmt; } \ 253 _Ostream_Manip(T) upcase( T val ) { return (_Ostream_Manip(T))@{ val, 1, 0,'G', { .all : 0 } }; } \250 _Ostream_Manip(T) upcase( T val ) { return (_Ostream_Manip(T))@{ .val : val, .wd : 1, .pc : 0, .base : 'G', { .all : 0 } }; } \ 254 251 _Ostream_Manip(T) & upcase( _Ostream_Manip(T) & fmt ) { fmt.base -= 32; /* upper case */ return fmt; } \ 255 252 _Ostream_Manip(T) & pad0( _Ostream_Manip(T) & fmt ) { fmt.flags.pad0 = true; return fmt; } \ 256 _Ostream_Manip(T) sign( T val ) { return (_Ostream_Manip(T))@{ val, 1, 0,'g', { .flags.sign : true } }; } \253 _Ostream_Manip(T) sign( T val ) { return (_Ostream_Manip(T))@{ .val : val, .wd : 1, .pc : 0, .base : 'g', { .flags.sign : true } }; } \ 257 254 _Ostream_Manip(T) & sign( _Ostream_Manip(T) & fmt ) { fmt.flags.sign = true; return fmt; } \ 258 _Ostream_Manip(T) nodp( T val ) { return (_Ostream_Manip(T))@{ val, 1, 0,'g', { .flags.nobsdp : true } }; } \255 _Ostream_Manip(T) nodp( T val ) { return (_Ostream_Manip(T))@{ .val : val, .wd : 1, .pc : 0, .base : 'g', { .flags.nobsdp : true } }; } \ 259 256 _Ostream_Manip(T) & nodp( _Ostream_Manip(T) & fmt ) { fmt.flags.nobsdp = true; return fmt; } \ 260 _Ostream_Manip(T) unit( T val ) { return (_Ostream_Manip(T))@{ val, 1, 0,'g', { .flags.nobsdp : true } }; } \257 _Ostream_Manip(T) unit( T val ) { return (_Ostream_Manip(T))@{ .val : val, .wd : 1, .pc : 0, .base : 'g', { .flags.nobsdp : true } }; } \ 261 258 _Ostream_Manip(T) & unit( _Ostream_Manip(T) & fmt ) { fmt.flags.nobsdp = true; return fmt; } \ 262 259 } /* distribution */ \ … … 272 269 273 270 static inline { 274 _Ostream_Manip(char) bin( char c ) { return (_Ostream_Manip(char))@{ c, 1, 0,'b', { .all : 0 } }; }275 _Ostream_Manip(char) oct( char c ) { return (_Ostream_Manip(char))@{ c, 1, 0,'o', { .all : 0 } }; }276 _Ostream_Manip(char) hex( char c ) { return (_Ostream_Manip(char))@{ c, 1, 0,'x', { .all : 0 } }; }277 _Ostream_Manip(char) wd( unsigned int w , char c ) { return (_Ostream_Manip(char))@{ c, w, 0,'c', { .all : 0 } }; }278 _Ostream_Manip(char) & wd( unsigned int w , _Ostream_Manip(char) & fmt ) { fmt.wd = w; return fmt; }271 _Ostream_Manip(char) bin( char c ) { return (_Ostream_Manip(char))@{ .val : c, .wd : 1, .pc : 0, .base : 'b', { .all : 0 } }; } 272 _Ostream_Manip(char) oct( char c ) { return (_Ostream_Manip(char))@{ .val : c, .wd : 1, .pc : 0, .base : 'o', { .all : 0 } }; } 273 _Ostream_Manip(char) hex( char c ) { return (_Ostream_Manip(char))@{ .val : c, .wd : 1, .pc : 0, .base : 'x', { .all : 0 } }; } 274 _Ostream_Manip(char) wd( unsigned int wd, char c ) { return (_Ostream_Manip(char))@{ c, wd, 0, .base : 'c', { .all : 0 } }; } 275 _Ostream_Manip(char) & wd( unsigned int wd, _Ostream_Manip(char) & fmt ) { fmt.wd = wd; return fmt; } 279 276 _Ostream_Manip(char) & left( _Ostream_Manip(char) & fmt ) { fmt.flags.left = true; return fmt; } 280 277 _Ostream_Manip(char) & upcase( _Ostream_Manip(char) & fmt ) { if ( fmt.base == 'x' || fmt.base == 'b' ) fmt.base -= 32; /* upper case */ return fmt; } … … 289 286 290 287 static inline { 291 _Ostream_Manip(const char *) bin( const char s[] ) { return (_Ostream_Manip(const char *))@{ s, 1, 0,'b', { .all : 0 } }; }292 _Ostream_Manip(const char *) oct( const char s[] ) { return (_Ostream_Manip(const char *))@{ s, 1, 0,'o', { .all : 0 } }; }293 _Ostream_Manip(const char *) hex( const char s[] ) { return (_Ostream_Manip(const char *))@{ s, 1, 0,'x', { .all : 0 } }; }294 _Ostream_Manip(const char *) wd( unsigned int w , const char s[] ) { return (_Ostream_Manip(const char *))@{ s, w, 0,'s', { .all : 0 } }; }295 _Ostream_Manip(const char *) wd( unsigned int w , unsigned int pc, const char s[] ) { return (_Ostream_Manip(const char *))@{ s, w, pc,'s', { .flags.pc : true } }; }296 _Ostream_Manip(const char *) & wd( unsigned int w , _Ostream_Manip(const char *) & fmt ) { fmt.wd = w; return fmt; }297 _Ostream_Manip(const char *) & wd( unsigned int w , unsigned int pc, _Ostream_Manip(const char *) & fmt ) { fmt.wd = w; fmt.pc = pc; fmt.flags.pc = true; return fmt; }288 _Ostream_Manip(const char *) bin( const char s[] ) { return (_Ostream_Manip(const char *))@{ .val : s, .wd : 1, .pc : 0, .base : 'b', { .all : 0 } }; } 289 _Ostream_Manip(const char *) oct( const char s[] ) { return (_Ostream_Manip(const char *))@{ .val : s, .wd : 1, .pc : 0, .base : 'o', { .all : 0 } }; } 290 _Ostream_Manip(const char *) hex( const char s[] ) { return (_Ostream_Manip(const char *))@{ .val : s, .wd : 1, .pc : 0, .base : 'x', { .all : 0 } }; } 291 _Ostream_Manip(const char *) wd( unsigned int wd, const char s[] ) { return (_Ostream_Manip(const char *))@{ s, wd, 0, .base : 's', { .all : 0 } }; } 292 _Ostream_Manip(const char *) wd( unsigned int wd, unsigned int pc, const char s[] ) { return (_Ostream_Manip(const char *))@{ s, .wd : wd, .pc : pc, .base : 's', { .flags.pc : true } }; } 293 _Ostream_Manip(const char *) & wd( unsigned int wd, _Ostream_Manip(const char *) & fmt ) { fmt.wd = wd; return fmt; } 294 _Ostream_Manip(const char *) & wd( unsigned int wd, unsigned int pc, _Ostream_Manip(const char *) & fmt ) { fmt.wd = wd; fmt.pc = pc; fmt.flags.pc = true; return fmt; } 298 295 _Ostream_Manip(const char *) & left( _Ostream_Manip(const char *) & fmt ) { fmt.flags.left = true; return fmt; } 299 296 _Ostream_Manip(const char *) & nobase( _Ostream_Manip(const char *) & fmt ) { fmt.flags.nobsdp = true; return fmt; } … … 385 382 386 383 static inline { 387 _Istream_Cskip skip( const char scanset[] ) { return (_Istream_Cskip)@{ scanset,0 }; }388 _Istream_Cskip skip( unsigned int wd ) { return (_Istream_Cskip)@{ 0p,wd }; }384 _Istream_Cskip skip( const char scanset[] ) { return (_Istream_Cskip)@{ .scanset : scanset, .wd : 0 }; } 385 _Istream_Cskip skip( unsigned int wd ) { return (_Istream_Cskip)@{ .scanset : 0p, .wd : wd }; } 389 386 } // distribution 390 387 … … 400 397 unsigned char ignore:1; // do not change input argument 401 398 unsigned char inex:1; // include/exclude characters in scanset 402 unsigned char delimiter:1; // delimit character 399 unsigned char delimiter:1; // delimit character(s) 403 400 unsigned char rwd:1; // read width 404 401 } flags; … … 406 403 }; // _Istream_str_base 407 404 408 struct _Istream_C str{405 struct _Istream_Cwidth { 409 406 char * s; 410 407 inline _Istream_str_base; 411 408 }; // _Istream_Cstr 412 409 410 // Restrict nesting of input manipulators to those combinations that make sense. 411 412 struct _Istream_Cstr { 413 _Istream_Cwidth cstr; 414 }; // _Istream_Cstr 415 413 416 struct _Istream_Cquoted { 414 _Istream_C strcstr;417 _Istream_Cwidth cstr; 415 418 }; // _Istream_Cquoted 416 419 417 420 static inline { 418 // width must include room for null terminator 419 _Istream_Cstr wdi( unsigned int wd, char s[] ) { return (_Istream_Cstr)@{ s, { {0p}, wd, {.all : 0} } }; } 420 _Istream_Cstr wdi( unsigned int wd, unsigned int rwd, char s[] ) { 421 if ( wd <= rwd ) throw (cstring_length){ &cstring_length_vt }; 422 return (_Istream_Cstr)@{ s, { {0p}, rwd, {.flags.rwd : true} } }; 421 // width must include room for null terminator, (gcc) scanf does not allow a 0 width => wd > 1 (1 char and null) and rd > 0 (1 char); 422 _Istream_Cwidth wdi( unsigned int wd, char s[] ) { 423 if ( wd <= 1 ) throw (cstring_length){ &cstring_length_vt }; // minimum 1 character and null terminator 424 return (_Istream_Cwidth)@{ .s : s, { {.scanset : 0p}, .wd : wd, {.all : 0} } }; 423 425 } 424 _Istream_C quoted & quoted( _Istream_Cstr & fmt, const char Ldelimiter = '"', const char Rdelimiter = '\0') {425 fmt.delimiters[0] = Ldelimiter; fmt.delimiters[1] = Rdelimiter; fmt.delimiters[2] = '\0';426 return (_Istream_C quoted &)fmt;426 _Istream_Cwidth wdi( unsigned int wd, unsigned int rwd, char s[] ) { 427 if ( wd <= 1 || wd <= rwd ) throw (cstring_length){ &cstring_length_vt }; // minimum 1 character, null terminator, plus subset 428 return (_Istream_Cwidth)@{ .s : s, { {.scanset : 0p}, .wd : rwd, {.flags.rwd : true} } }; 427 429 } 428 _Istream_C str & getline( _Istream_Cstr & fmt, const char delimiter = '\n' ) {429 fmt.delimiters[0] = delimiter; fmt.delimiters[1] = '\0'; fmt.flags.delimiter = true; fmt.flags.inex = true; return fmt;430 _Istream_Cquoted quoted( char & ch, const char Ldelimiter = '\'', const char Rdelimiter = '\0' ) { 431 return (_Istream_Cquoted)@{ { .s : &ch, { {.delimiters : { Ldelimiter, Rdelimiter, '\1' }}, .wd : 1, {.flags.rwd : true} } } }; 430 432 } 431 _Istream_Cstr & incl( const char scanset[], _Istream_Cstr & fmt ) { fmt.scanset = scanset; fmt.flags.inex = false; return fmt; } 432 _Istream_Cstr & excl( const char scanset[], _Istream_Cstr & fmt ) { fmt.scanset = scanset; fmt.flags.inex = true; return fmt; } 433 _Istream_Cstr ignore( char s[] ) { return (_Istream_Cstr)@{ s, { {0p}, -1, {.flags.ignore : true} } }; } 434 _Istream_Cstr & ignore( _Istream_Cstr & fmt ) { fmt.flags.ignore = true; return fmt; } 433 _Istream_Cquoted & quoted( _Istream_Cwidth & f, const char Ldelimiter = '"', const char Rdelimiter = '\0' ) { 434 f.delimiters[0] = Ldelimiter; f.delimiters[1] = Rdelimiter; f.delimiters[2] = '\0'; 435 return (_Istream_Cquoted &)f; 436 } 437 _Istream_Cstr & getline( _Istream_Cwidth & f, const char delimiter = '\n' ) { 438 f.delimiters[0] = delimiter; f.delimiters[1] = '\0'; f.flags.delimiter = true; return (_Istream_Cstr &)f; 439 } 440 _Istream_Cstr & incl( const char scanset[], _Istream_Cwidth & f ) { f.scanset = scanset; f.flags.inex = false; return (_Istream_Cstr &)f; } 441 _Istream_Cstr & excl( const char scanset[], _Istream_Cwidth & f ) { f.scanset = scanset; f.flags.inex = true; return (_Istream_Cstr &)f; } 442 _Istream_Cstr ignore( const char s[] ) { return (_Istream_Cwidth)@{ .s : (char *)s, { {.scanset : 0p}, .wd : -1, {.flags.ignore : true} } }; } 443 _Istream_Cstr & ignore( _Istream_Cwidth & f ) { f.flags.ignore = true; return (_Istream_Cstr &)f; } 444 _Istream_Cquoted & ignore( _Istream_Cquoted & f ) { f.cstr.flags.ignore = true; return (_Istream_Cquoted &)f; } 445 _Istream_Cstr & ignore( _Istream_Cstr & f ) { f.cstr.flags.ignore = true; return (_Istream_Cstr &)f; } 435 446 } // distribution 436 447 437 448 forall( istype & | basic_istream( istype ) ) { 438 istype & ?|?( istype & is, _Istream_Cstr f );439 449 istype & ?|?( istype & is, _Istream_Cskip f ); 440 450 istype & ?|?( istype & is, _Istream_Cquoted f ); 441 } // distribution 442 443 struct _Istream_Char { 444 bool ignore; // do not change input argument 445 }; // _Istream_Char 446 447 static inline { 448 _Istream_Char ignore( const char ) { return (_Istream_Char)@{ true }; } 449 _Istream_Char & ignore( _Istream_Char & fmt ) { fmt.ignore = true; return fmt; } 450 } // distribution 451 forall( istype & | basic_istream( istype ) ) { 452 istype & ?|?( istype & is, _Istream_Char f ); 453 } 451 istype & ?|?( istype & is, _Istream_Cstr f ); 452 static inline { 453 istype & ?|?( istype & is, _Istream_Cwidth f ) { return is | *(_Istream_Cstr *)&f; } 454 } // distribution 455 } // distribution 454 456 455 457 forall( T & | sized( T ) ) … … 462 464 #define INPUT_FMT_DECL( T ) \ 463 465 static inline { \ 464 _Istream_Manip(T) ignore( const T & val ) { return (_Istream_Manip(T))@{ (T &)val, -1, true }; } \ 466 _Istream_Manip(T) wdi( unsigned int wd, T & val ) { return (_Istream_Manip(T))@{ .val : val, .wd : wd, .ignore : false }; } \ 467 _Istream_Manip(T) ignore( const T & val ) { return (_Istream_Manip(T))@{ .val : (T &)val, .wd : -1, .ignore : true }; } \ 465 468 _Istream_Manip(T) & ignore( _Istream_Manip(T) & fmt ) { fmt.ignore = true; return fmt; } \ 466 _Istream_Manip(T) wdi( unsigned int wd, T & val ) { return (_Istream_Manip(T))@{ val, wd, false }; } \467 _Istream_Manip(T) & wdi( unsigned int wd, _Istream_Manip(T) & fmt ) { fmt.wd = wd; return fmt; } \468 469 } /* distribution */ \ 469 470 forall( istype & | basic_istream( istype ) ) { \ … … 471 472 } // ?|? 472 473 474 INPUT_FMT_DECL( char ) 473 475 INPUT_FMT_DECL( signed char ) 474 476 INPUT_FMT_DECL( unsigned char ) -
src/Common/utility.h
rc75b30a r32490deb 111 111 }; 112 112 113 // -----------------------------------------------------------------------------114 // O(1) polymorphic integer ilog2, using clz, which returns the number of leading 0-bits, starting at the most115 // significant bit (single instruction on x86)116 117 template<typename T>118 inline119 #if defined(__GNUC__) && __GNUC__ > 4120 constexpr121 #endif122 T ilog2(const T & t) {123 if(std::is_integral<T>::value) {124 const constexpr int r = sizeof(t) * __CHAR_BIT__ - 1;125 if( sizeof(T) == sizeof(unsigned int) ) return r - __builtin_clz ( t );126 if( sizeof(T) == sizeof(unsigned long) ) return r - __builtin_clzl ( t );127 if( sizeof(T) == sizeof(unsigned long long) ) return r - __builtin_clzll( t );128 }129 assert(false);130 return -1;131 } // ilog2132 133 113 // Local Variables: // 134 114 // tab-width: 4 // -
src/ResolvExpr/Resolver.cc
rc75b30a r32490deb 50 50 51 51 namespace ResolvExpr { 52 template< typename iterator_t >53 inline bool advance_to_mutex( iterator_t & it, const iterator_t & end ) {54 while( it != end && !(*it)->get_type()->get_mutex() ) {55 it++;56 }57 58 return it != end;59 }60 61 52 namespace { 62 53 /// Finds deleted expressions in an expression tree -
tests/collections/.expect/string-istream-manip.txt
rc75b30a r32490deb 68 68 12 wwwwwwww 69 69 13 wwwwwwww 70 14 cccc70 14 71 71 15 72 72 1 yyyyyyyyyyyyyyyyyyyy … … 83 83 12 wwwwwwww 84 84 13 wwwwwwww 85 14 cccc85 14 86 86 15 -
tests/collections/.in/string-istream-manip.txt
rc75b30a r32490deb 36 36 abcxxx 37 37 abcyyy 38 aaaaaaaaxxxxxxxxaabbccbbdddwwwbbbbbbbbwwwwwwwwaaaaaaaawwwwwwww 39 uuuuu ccccuuuuu38 aaaaaaaaxxxxxxxxaabbccbbdddwwwbbbbbbbbwwwwwwwwaaaaaaaawwwwwwwwaaaaaaaawwwwwwww 39 uuuuu 40 40 abc 41 41 cccccb … … 43 43 abcxxx 44 44 abcyyy 45 aaaaaaaaxxxxxxxxaabbccbbdddwwwbbbbbbbbwwwwwwwwaaaaaaaawwwwwwww 46 uuuuu ccccuuuuu45 aaaaaaaaxxxxxxxxaabbccbbdddwwwbbbbbbbbwwwwwwwwaaaaaaaawwwwwwwwaaaaaaaawwwwwwww 46 uuuuu -
tests/collections/string-istream-manip.cfa
rc75b30a r32490deb 165 165 sin | ignore( incl( "abc", wdi( 8, s ) ) ); sout | "12" | s; 166 166 sin | ignore( excl( "abc", wdi( 8, s ) ) ); sout | "13" | s; 167 sin | "\n"; 167 168 168 169 s = "q"; … … 191 192 sin | ignore( incl( "abc", wdi( 8, s ) ) ); sout | "12" | s; 192 193 sin | ignore( excl( "abc", wdi( 8, s ) ) ); sout | "13" | s; 194 sin | "\n"; 193 195 194 196 s = "q"; -
tests/io/.expect/manipulatorsInput.arm64.txt
rc75b30a r32490deb 18 18 12 wwwwwwww 19 19 13 wwwwwwww 20 14 rc= 1, cccc20 14 rc=0, q 21 21 15 rc=0, q 22 22 16 get this line 23 23 17 @# this line 1)-{} 24 18 abc 25 19 abc 26 20 d d 24 18 @# this line 1)-{} 25 19 abc 26 20 abc 27 21 d d 27 28 28 29 d 29 21 ZC44% 30 22 ZC44% 31 23 ZC44% 32 24 x 33 25 x 34 26 x 35 27 x 36 28 x 30 37 1 yyyyyyyyyyyyyyyyyyyy 31 38 2 abcxxx 32 39 3 abcxxx 33 40 4 aaaaaaaa 34 5 41 5 aaaaaaaa 35 42 6 aabbccbb 36 43 7 dddwww 37 8 38 9 44 8 dddwww 45 9 dddwww 39 46 10 aaaaaaaa 40 47 11 wwwwwwww 41 12 42 13 43 14 cccc48 12 wwwwwwww 49 13 wwwwwwww 50 14 44 51 15 45 52 16 get this line 46 53 17 @# this line 1)-{} 47 18 abc 48 19 abc 49 20 d d 54 18 @# this line 1)-{} 55 19 abc 56 20 abc 57 21 d d 50 58 51 59 d 52 21 ZC44% 60 22 ZC44% 61 23 ZC44% 62 24 x 63 25 x 64 26 x 65 27 x 66 28 x 53 67 a 54 68 a 69 xxx 70 xxx 55 71 -1 56 72 15 -
tests/io/.expect/manipulatorsInput.x64.txt
rc75b30a r32490deb 18 18 12 wwwwwwww 19 19 13 wwwwwwww 20 14 rc= 1, cccc20 14 rc=0, q 21 21 15 rc=0, q 22 22 16 get this line 23 23 17 @# this line 1)-{} 24 18 abc 25 19 abc 26 20 d d 24 18 @# this line 1)-{} 25 19 abc 26 20 abc 27 21 d d 27 28 28 29 d 29 21 ZC44% 30 22 ZC44% 31 23 ZC44% 32 24 x 33 25 x 34 26 x 35 27 x 36 28 x 30 37 1 yyyyyyyyyyyyyyyyyyyy 31 38 2 abcxxx 32 39 3 abcxxx 33 40 4 aaaaaaaa 34 5 41 5 aaaaaaaa 35 42 6 aabbccbb 36 43 7 dddwww 37 8 38 9 44 8 dddwww 45 9 dddwww 39 46 10 aaaaaaaa 40 47 11 wwwwwwww 41 12 42 13 43 14 cccc48 12 wwwwwwww 49 13 wwwwwwww 50 14 44 51 15 45 52 16 get this line 46 53 17 @# this line 1)-{} 47 18 abc 48 19 abc 49 20 d d 54 18 @# this line 1)-{} 55 19 abc 56 20 abc 57 21 d d 50 58 51 59 d 52 21 ZC44% 60 22 ZC44% 61 23 ZC44% 62 24 x 63 25 x 64 26 x 65 27 x 66 28 x 53 67 a 54 68 a 69 xxx 70 xxx 55 71 -1 56 72 15 -
tests/io/.expect/manipulatorsInput.x86.txt
rc75b30a r32490deb 18 18 12 wwwwwwww 19 19 13 wwwwwwww 20 14 rc= 1, cccc20 14 rc=0, q 21 21 15 rc=0, q 22 22 16 get this line 23 23 17 @# this line 1)-{} 24 18 abc 25 19 abc 26 20 d d 24 18 @# this line 1)-{} 25 19 abc 26 20 abc 27 21 d d 27 28 28 29 d 29 21 ZC44% 30 22 ZC44% 31 23 ZC44% 32 24 x 33 25 x 34 26 x 35 27 x 36 28 x 30 37 1 yyyyyyyyyyyyyyyyyyyy 31 38 2 abcxxx 32 39 3 abcxxx 33 40 4 aaaaaaaa 34 5 41 5 aaaaaaaa 35 42 6 aabbccbb 36 43 7 dddwww 37 8 38 9 44 8 dddwww 45 9 dddwww 39 46 10 aaaaaaaa 40 47 11 wwwwwwww 41 12 42 13 43 14 cccc48 12 wwwwwwww 49 13 wwwwwwww 50 14 44 51 15 45 52 16 get this line 46 53 17 @# this line 1)-{} 47 18 abc 48 19 abc 49 20 d d 54 18 @# this line 1)-{} 55 19 abc 56 20 abc 57 21 d d 50 58 51 59 d 52 21 ZC44% 60 22 ZC44% 61 23 ZC44% 62 24 x 63 25 x 64 26 x 65 27 x 66 28 x 53 67 a 54 68 a 69 xxx 70 xxx 55 71 -1 56 72 15 -
tests/io/.in/manipulatorsInput.txt
rc75b30a r32490deb 8 8 abcxxx 9 9 abcyyy 10 aaaaaaaaxxxxxxxxaabbccbbdddwwwbbbbbbbbwwwwwwwwaaaaaaaawwwwwwww 11 uuuuu ccccuuuuu10 aaaaaaaaxxxxxxxxaabbccbbdddwwwbbbbbbbbwwwwwwwwaaaaaaaawwwwwwwwaaaaaaaawwwwwwww 11 uuuuu 12 12 get this line 13 13 @# this line 1)-{}% 14 @# this line 2)-{}% 14 15 "abc" 15 16 'abc ' … … 18 19 d } 19 20 X ZC44%Y 21 X ZC55%Y 22 'x' 23 "x" 24 {x} 25 XxY 26 XyY 20 27 abc 21 28 cccccb … … 23 30 abcxxx 24 31 abcyyy 25 aaaaaaaaxxxxxxxxaabbccbbdddwwwbbbbbbbbwwwwwwwwaaaaaaaawwwwwwww 26 uuuuu ccccuuuuu32 aaaaaaaaxxxxxxxxaabbccbbdddwwwbbbbbbbbwwwwwwwwaaaaaaaawwwwwwwwaaaaaaaawwwwwwww 33 uuuuu 27 34 get this line 28 35 @# this line 1)-{}% 36 @# this line 2)-{}% 29 37 "abc" 30 38 'abc ' … … 33 41 d } 34 42 X ZC44%Y 43 X ZC55%Y 44 'x' 45 "x" 46 {x} 47 XxY 48 XyY 35 49 ab 50 xxxyyy 36 51 0xff 017 15-15 37 52 0xff 017 15-15 -
tests/io/manipulatorsInput.cfa
rc75b30a r32490deb 7 7 // Created On : Sat Jun 8 17:58:54 2019 8 8 // Last Modified By : Peter A. Buhr 9 // Last Modified On : Wed Jan 3 11:15:04202410 // Update Count : 1 039 // Last Modified On : Sun Jan 28 11:59:55 2024 10 // Update Count : 133 11 11 // 12 12 … … 55 55 } 56 56 { 57 char s[] = "yyyyyyyyyyyyyyyyyyyy"; 57 char s[] = "yyyyyyyyyyyyyyyyyyyy"; // Input characters consumed: 58 58 const char sk_fmt[] = "%*[abc]"; 59 scanf( "abc " ); scanf( sk_fmt ); for ( 5 ) scanf( "%*c" ); printf( "1 %s\n", s ); 60 scanf( "%s", s ); printf( "2 %s\n", s ); 61 scanf( "%*s" ); printf( "3 %s\n", s ); 62 scanf( "%8s", s ); printf( "4 %s\n", s ); 63 scanf( "%*8s" ); printf( "5 %s\n", s ); 64 65 scanf( "%[abc]", s ); printf( "6 %s\n", s ); 66 scanf( "%[^abc]", s ); printf( "7 %s\n", s ); 67 scanf( "%*[abc]" ); printf( "8 %s\n", s ); 68 scanf( "%*[^abc]" ); printf( "9 %s\n", s ); 69 scanf( "%8[abc]", s ); printf( "10 %s\n", s ); 70 scanf( "%8[^abc]", s ); printf( "11 %s\n", s ); 71 scanf( "%*8[abc]" ); printf( "12 %s\n", s ); 72 scanf( "%*8[^abc]" ); printf( "13 %s\n", s ); 59 scanf( "abc " ); scanf( sk_fmt ); for ( 5 ) scanf( "%*c" ); printf( "1 %s\n", s ); // |abc |\ncccccb| \nxx\n| 60 scanf( "%s", s ); printf( "2 %s\n", s ); // |abcxxx| 61 scanf( "%*s" ); printf( "3 %s\n", s ); // |\nabcyyy| 62 scanf( "%8s", s ); printf( "4 %s\n", s ); // |\naaaaaaaa| 63 scanf( "%*8s" ); printf( "5 %s\n", s ); // |xxxxxxxx| 64 65 scanf( "%[abc]", s ); printf( "6 %s\n", s ); // |aabbccbb| 66 scanf( "%[^abc]", s ); printf( "7 %s\n", s ); // |dddwww| 67 scanf( "%*[abc]" ); printf( "8 %s\n", s ); // |bbbbbbbb| 68 scanf( "%*[^abc]" ); printf( "9 %s\n", s ); // |wwwwwwww| 69 scanf( "%8[abc]", s ); printf( "10 %s\n", s ); // |aaaaaaaa| 70 scanf( "%8[^abc]", s ); printf( "11 %s\n", s ); // |wwwwwwww| 71 scanf( "%*8[abc]" ); printf( "12 %s\n", s ); // |aaaaaaaa| 72 scanf( "%*8[^abc]" ); printf( "13 %s\n", s ); // |wwwwwwww| 73 scanf( "\n" ); // must start next line // |\n| 73 74 74 75 int rc; 75 76 s[0] = 'q'; s[1] = '\0'; rc = 99; 76 rc = scanf( "%[abc]", s ); printf( "14 rc=%d, %s\n", rc, s ); 77 rc = scanf( "%[abc]", s ); printf( "14 rc=%d, %s\n", rc, s ); // || 77 78 s[0] = 'q'; s[1] = '\0'; rc = 99; 78 rc = scanf( "%[^u]", s ); printf( "15 rc=%d, %s\n", rc, s ); 79 scanf( "%*[u]\n" ); 80 scanf( "%[^\n]\n", s ); printf( "16 %s\n", s ); 81 scanf( "%[^%%]%%\n", s ); printf( "17 %s\n", s ); 82 83 scanf( "%*[ \f\n\r\t\v]" ); // ignore whitespace 84 scanf( "\"%[^\"]\"", s ); printf( "18 %s\n", s ); 85 scanf( "%*[ \f\n\r\t\v]" ); // ignore whitespace 86 scanf( "'%[^']'", s ); printf( "19 %s\n", s ); 87 scanf( "%*[ \f\n\r\t\v]" ); // ignore whitespace 88 scanf( "{%[^}]}", s ); printf( "20 %s\n", s ); 89 scanf( "%*[ \f\n\r\t\v]" ); // ignore whitespace 90 scanf( "X%[^Y]Y", s ); printf( "21 %s\n", s ); 91 scanf( "\n" ); // must start next line 79 rc = scanf( "%[^u]", s ); printf( "15 rc=%d, %s\n", rc, s ); // || 80 scanf( "%*[u]\n" ); // |uuuuu\n| 81 scanf( "%[^\n]\n", s ); printf( "16 %s\n", s ); // |get this line\n| 82 scanf( "%[^%%]%%\n", s ); printf( "17 %s\n", s ); // |@# this line 1)-{}%\n| 83 scanf( "%*[^%%]%%\n", s ); printf( "18 %s\n", s ); // |@# this line 1)-{}%\n| 84 85 scanf( "%*[ \f\n\r\t\v]" ); // ignore whitespace // || 86 scanf( "\"%[^\"]\"", s ); printf( "19 %s\n", s ); // |"abc"| 87 scanf( "%*[ \f\n\r\t\v]" ); // ignore whitespace // |\n| 88 scanf( "'%[^']'", s ); printf( "20 %s\n", s ); // |'abc '| 89 scanf( "%*[ \f\n\r\t\v]" ); // ignore whitespace // |\n| 90 scanf( "{%[^}]}", s ); printf( "21 %s\n", s ); // |{ d d\n\nd }| 91 scanf( "%*[ \f\n\r\t\v]" ); // ignore whitespace // |\n| 92 scanf( "X%[^Y]Y", s ); printf( "22 %s\n", s ); // |X ZC44%Y| 93 scanf( "%*[ \f\n\r\t\v]" ); // ignore whitespace // |\n| 94 scanf( "X%*[^Y]Y", s ); printf( "23 %s\n", s ); // |X ZC44%Y| 95 scanf( "\n" ); // must start next line // |\n| 96 97 char ch; 98 scanf( "%*[ \f\n\r\t\v]" ); // ignore whitespace // |\n| 99 scanf( "'%c'", &ch ); printf( "24 %c\n", ch ); // |x| 100 scanf( "%*[ \f\n\r\t\v]" ); // ignore whitespace // |\n| 101 scanf( "\"%c\"", &ch ); printf( "25 %c\n", ch ); // |x| 102 scanf( "%*[ \f\n\r\t\v]" ); // ignore whitespace // |\n| 103 scanf( "{%c}", &ch ); printf( "26 %c\n", ch ); // |x| 104 scanf( "%*[ \f\n\r\t\v]" ); // ignore whitespace // |\n| 105 scanf( "X%cY", &ch ); printf( "27 %c\n", ch ); // |x| 106 scanf( "%*[ \f\n\r\t\v]" ); // ignore whitespace // |\n| 107 scanf( "X%*cY", &ch ); printf( "28 %c\n", ch ); // |x| 108 scanf( "\n" ); // must start next line // |\n| 92 109 } 93 110 { … … 108 125 sin | ignore( incl( "abc", wdi( sizeof(s), 8, s ) ) ); sout | "12" | s; 109 126 sin | ignore( excl( "abc", wdi( sizeof(s), 8, s ) ) ); sout | "13" | s; 127 sin | nl; 110 128 111 129 s[0] = 'q'; s[1] = '\0'; … … 116 134 sin | getline( wdi( sizeof(s), s ) ); sout | "16" | s; 117 135 sin | getline( wdi( sizeof(s), s ), '%' ) | "\n"; sout | "17" | s; 118 119 sin | quoted( wdi( sizeof(s), s ) ); sout | "18" | s; 120 sin | quoted( wdi( sizeof(s), s ), '\'' ); sout | "19" | s; 121 sin | quoted( wdi( sizeof(s), s ), '{', '}' ); sout | "20" | s; 122 sin | quoted( wdi( sizeof(s), s ), 'X', 'Y' ); sout | "21" | s; 123 } 124 // Keep harmonized with collections/string-istream-manip 136 sin | ignore( getline( wdi( sizeof(s), s ), '%' ) ) | "\n"; sout | "18" | s; 137 138 sin | quoted( wdi( sizeof(s), s ) ); sout | "19" | s; 139 sin | quoted( wdi( sizeof(s), s ), '\'' ); sout | "20" | s; 140 sin | quoted( wdi( sizeof(s), s ), '{', '}' ); sout | "21" | s; 141 sin | quoted( wdi( sizeof(s), s ), 'X', 'Y' ); sout | "22" | s; 142 sin | ignore( quoted( wdi( sizeof(s), s ), 'X', 'Y' ) ); sout | "23" | s; 143 144 char ch; 145 sin | quoted( ch ); sout | "24 " | ch; 146 sin | quoted( ch, '\"' ); sout | "25 " | ch; 147 sin | quoted( ch, '{', '}' ); sout | "26 " | ch; 148 sin | quoted( ch, 'X', 'Y' ); sout | "27 " | ch; 149 sin | ignore( quoted( ch, 'X', 'Y' ) ); sout | "28 " | ch; 150 sin | nl; 151 } 152 // Keep harmonized with collections/string-istream-manip 125 153 { 126 154 char c; 127 155 sin | c; sout | c; 128 156 sin | ignore( c ); sout | c; 157 sin | nl; 158 159 char ca[3] = { 'a', 'b', 'c' }; 160 sin | wdi( sizeof(ca), ca[0] ); sout | ca[0] | ca[1] | ca[2]; 161 sin | ignore( wdi( sizeof(ca), ca[0] ) ); sout | ca[0] | ca[1] | ca[2]; 162 sin | nl; 129 163 130 164 signed char sc;
Note:
See TracChangeset
for help on using the changeset viewer.