Changes in / [a0c7d5cc:534d84e]
- Files:
-
- 18 edited
Legend:
- Unmodified
- Added
- Removed
-
doc/papers/AMA/AMA-stix/ama/WileyNJD-v2.cls
ra0c7d5cc r534d84e 484 484 \if@STIXLargeOneCol% 485 485 \RequirePackage[not1,notextcomp,lcgreekalpha]{stix}% 486 \usepackage[scaled]{helvet}487 \renewcommand\familydefault{\sfdefault}486 %\usepackage[scaled]{helvet} 487 %\renewcommand\familydefault{\sfdefault} 488 488 \usepackage[T1]{fontenc} 489 489 \BXhsize=170mm% … … 966 966 % Footnotes 967 967 % 968 % \renewcommand\thefootnote{\@fnsymbol\c@footnote}%968 %%\renewcommand\thefootnote{\@fnsymbol\c@footnote}% 969 969 970 970 … … 1279 1279 1280 1280 \if@font@stix% 1281 \def\footnotetextfont{\ sffamily\fontsize{8bp}{10bp}\selectfont}\else%1281 \def\footnotetextfont{\rmfamily\fontsize{8bp}{10bp}\selectfont}\else% 1282 1282 %% 1283 \def\footnotetextfont{\ sffamily\fontsize{6bp}{8bp}\selectfont}1283 \def\footnotetextfont{\rmfamily\fontsize{6bp}{8bp}\selectfont} 1284 1284 \fi% 1285 1285 % … … 1294 1294 \DeclareRobustCommand\sfitseries{\not@math@alphabet\sfitseries\normalfont\fontseries{m}\fontshape{it}\selectfont} 1295 1295 \DeclareTextFontCommand{\textsfi}{\sfitseries} 1296 \DeclareOldFontCommand{\rm}{\normalfont\ sffamily}{\mathrm}1296 \DeclareOldFontCommand{\rm}{\normalfont\rmfamily}{\mathrm} 1297 1297 \DeclareOldFontCommand{\sf}{\normalfont\sffamily}{\mathsf} 1298 1298 \DeclareOldFontCommand{\tt}{\normalfont\ttfamily}{\mathtt} … … 1322 1322 \renewcommand\normalsize{% 1323 1323 \if@font@stix% 1324 \@setfontsize\normalsize{ 9bp}{12bp}%1324 \@setfontsize\normalsize{10bp}{13bp}% 1325 1325 \else% 1326 1326 \@setfontsize\normalsize{8bp}{13bp}% … … 1418 1418 % \def\watermarkfont{\reset@font\fontfamily{\ffdefault}\fontsize{45}{45}\bfseries\selectfont} 1419 1419 % 1420 \def\pagenumfont{\ sffamily\fontsize{7}{9}\bfseries\selectfont}%1421 \def\cnmpagenumfont{\ sffamily\fontsize{7}{9}\selectfont\bfseries}%1422 %%% \def\runningheadfont{\ sffamily\fontsize{7}{9}\scshape\selectfont}%1423 \def\runningheadfont{\ sffamily\fontsize{7}{9}\selectfont}%New updations 19aug20161424 \def\runningfootfont{\ sffamily\fontsize{7}{9}\selectfont}%1425 \def\titlepageheadfont{\ sffamily\fontsize{7}{9}\selectfont}%1420 \def\pagenumfont{\rmfamily\fontsize{7}{9}\bfseries\selectfont}% 1421 \def\cnmpagenumfont{\rmfamily\fontsize{7}{9}\selectfont\bfseries}% 1422 %%% \def\runningheadfont{\rmfamily\fontsize{7}{9}\scshape\selectfont}% 1423 \def\runningheadfont{\rmfamily\fontsize{7}{9}\selectfont}%New updations 19aug2016 1424 \def\runningfootfont{\rmfamily\fontsize{7}{9}\selectfont}% 1425 \def\titlepageheadfont{\rmfamily\fontsize{7}{9}\selectfont}% 1426 1426 % 1427 \def\BRarttypefont{\reset@font\ sffamily\fontsize{18}{18}\fontseries{b}\selectfont}%1428 \def\pubheadfont{\reset@font\ sffamily\fontsize{7}{9}\fontseries{b}\selectfont}%1429 \def\arttypefont{\ sffamily\fontsize{9}{9}\fontseries{b}\selectfont}%1430 \def\SParttypefont{\ sffamily\fontsize{9}{12}\fontseries{b}\selectfont}%1431 \def\titlefont{\ sffamily\fontsize{18}{23}\bfseries\selectfont\leftskip\z@\rightskip\z@ plus1fil}%1432 \def\subtitlefont{\ sffamily\fontsize{16}{21}\bfseries\selectfont\leftskip\z@\rightskip\z@ plus1fil}%1433 \def\Authorfont{\ sffamily\fontsize{12}{18}\selectfont\leftskip\z@\rightskip\z@ plus1fil}%1434 \def\absheadfont{\hsize\abs@colii@hsize\ sffamily\fontsize{10}{10}\fontseries{b}\selectfont\bfseries\leftskip7\p@\rightskip\leftskip}% LN20FEB20161435 \def\legalstatementfont{\ sffamily\fontsize{7}{10}\selectfont\leftskip0\p@\rightskip\leftskip}%1436 \def\BRsectionfont{\ sffamily\fontsize{10}{16}\fontseries{b}\selectfont\leftskip\z@\rightskip\z@ plus1fil}%1437 \def\sectionfont{\ sffamily\fontsize{12}{13}\fontseries{b}\selectfont\leftskip\z@\rightskip\z@ plus1fil}%1438 \def\subsectionfont{\ sffamily\fontsize{12}{13}\bfseries\selectfont\leftskip\z@\rightskip\z@ plus1fil}%1439 \def\subsubsectionfont{\ sffamily\fontsize{12}{13}\bfseries\selectfont\leftskip\z@\rightskip\z@ plus1fil}%1440 \def\paragraphfont{\ sffamily\fontsize{10.5}{13}\fontseries{b}\selectfont}%1441 \def\subparagraphfont{\ sffamily\fontsize{10}{13}\fontseries{b}\selectfont}%1442 \def\appsectionfont{\ sffamily\fontsize{10}{13}\fontseries{b}\selectfont\leftskip\z@\rightskip\z@ plus1fil}%1427 \def\BRarttypefont{\reset@font\rmfamily\fontsize{18}{18}\fontseries{b}\selectfont}% 1428 \def\pubheadfont{\reset@font\rmfamily\fontsize{7}{9}\fontseries{b}\selectfont}% 1429 \def\arttypefont{\rmfamily\fontsize{9}{9}\fontseries{b}\selectfont}% 1430 \def\SParttypefont{\rmfamily\fontsize{9}{12}\fontseries{b}\selectfont}% 1431 \def\titlefont{\rmfamily\fontsize{18}{23}\bfseries\selectfont\leftskip\z@\rightskip\z@ plus1fil}% 1432 \def\subtitlefont{\rmfamily\fontsize{16}{21}\bfseries\selectfont\leftskip\z@\rightskip\z@ plus1fil}% 1433 \def\Authorfont{\rmfamily\fontsize{12}{18}\selectfont\leftskip\z@\rightskip\z@ plus1fil}% 1434 \def\absheadfont{\hsize\abs@colii@hsize\rmfamily\fontsize{10}{10}\fontseries{b}\selectfont\bfseries\leftskip7\p@\rightskip\leftskip}% LN20FEB2016 1435 \def\legalstatementfont{\rmfamily\fontsize{7}{10}\selectfont\leftskip0\p@\rightskip\leftskip}% 1436 \def\BRsectionfont{\rmfamily\fontsize{10}{16}\fontseries{b}\selectfont\leftskip\z@\rightskip\z@ plus1fil}% 1437 \def\sectionfont{\rmfamily\fontsize{12}{13}\fontseries{b}\selectfont\leftskip\z@\rightskip\z@ plus1fil}% 1438 \def\subsectionfont{\rmfamily\fontsize{12}{13}\bfseries\selectfont\leftskip\z@\rightskip\z@ plus1fil}% 1439 \def\subsubsectionfont{\rmfamily\fontsize{12}{13}\bfseries\selectfont\leftskip\z@\rightskip\z@ plus1fil}% 1440 \def\paragraphfont{\rmfamily\fontsize{10.5}{13}\fontseries{b}\selectfont}% 1441 \def\subparagraphfont{\rmfamily\fontsize{10}{13}\fontseries{b}\selectfont}% 1442 \def\appsectionfont{\rmfamily\fontsize{10}{13}\fontseries{b}\selectfont\leftskip\z@\rightskip\z@ plus1fil}% 1443 1443 % 1444 \def\boxheadfont{\ sffamily\fontsize{10}{13}\fontseries{b}\selectfont}1445 \def\boxtitlefont{\ sffamily\fontsize{10}{13}\bfseries\selectfont}1444 \def\boxheadfont{\rmfamily\fontsize{10}{13}\fontseries{b}\selectfont} 1445 \def\boxtitlefont{\rmfamily\fontsize{10}{13}\bfseries\selectfont} 1446 1446 % 1447 \def\GnSabsfont{\ sffamily\fontsize{9}{15}\selectfont}%1448 \def\GnSabsfootfont{\reset@font\ sffamily\fontsize{14}{0}\bfseries\selectfont}%1447 \def\GnSabsfont{\rmfamily\fontsize{9}{15}\selectfont}% 1448 \def\GnSabsfootfont{\reset@font\rmfamily\fontsize{14}{0}\bfseries\selectfont}% 1449 1449 % 1450 \def\suppinfofont{\noindent\ sffamily}%1450 \def\suppinfofont{\noindent\rmfamily}% 1451 1451 \def\suppinfoheadfont{\noindent\fontsize{10}{13}\fontseries{b}\selectfont}% 1452 \def\suppinfocaptionfont{\noindent\ sffamily}%1452 \def\suppinfocaptionfont{\noindent\rmfamily}% 1453 1453 % 1454 \def\figurenumfont{\ sffamily\fontsize{9bp}{12}\fontseries{b}\selectfont}%1455 \def\figurecaptionfont{\ sffamily\fontsize{8.5bp}{12}\selectfont}1454 \def\figurenumfont{\rmfamily\fontsize{9bp}{12}\fontseries{b}\selectfont}% 1455 \def\figurecaptionfont{\rmfamily\fontsize{8.5bp}{12}\selectfont} 1456 1456 \def\bwfiginfofont{\fontfamily{tim}\fontsize{10bp}{10bp}\selectfont}% 1457 1457 % 1458 \def\tablenumfont{\ sffamily\fontsize{9bp}{11.5bp}\fontseries{b}\selectfont}%1459 \def\keypointheadfont{\reset@font\ sffamily\fontsize{10bp}{13bp}\fontseries{b}\selectfont}%1460 \def\tablecaptionfont{\ sffamily\fontsize{8.5bp}{12bp}\selectfont}1461 \def\tablebodyfont{\ sffamily\fontsize{8.5bp}{11.5bp}\selectfont}1462 \def\tablecolheadfont{\ sffamily\fontsize{8.5bp}{11.5bp}\selectfont\bfseries}1463 \def\tablefootnotefont{\ sffamily\fontsize{7.5bp}{10.5bp}\selectfont}1458 \def\tablenumfont{\rmfamily\fontsize{9bp}{11.5bp}\fontseries{b}\selectfont}% 1459 \def\keypointheadfont{\reset@font\rmfamily\fontsize{10bp}{13bp}\fontseries{b}\selectfont}% 1460 \def\tablecaptionfont{\rmfamily\fontsize{8.5bp}{12bp}\selectfont} 1461 \def\tablebodyfont{\rmfamily\fontsize{8.5bp}{11.5bp}\selectfont} 1462 \def\tablecolheadfont{\rmfamily\fontsize{8.5bp}{11.5bp}\selectfont\bfseries} 1463 \def\tablefootnotefont{\rmfamily\fontsize{7.5bp}{10.5bp}\selectfont} 1464 1464 % 1465 %% \def\footnotetextfont{\ sffamily\fontsize{8bp}{10bp}\selectfont}1465 %% \def\footnotetextfont{\rmfamily\fontsize{8bp}{10bp}\selectfont} 1466 1466 % 1467 1467 \def\listfont{\normalsize}% … … 1473 1473 % 1474 1474 \def\ackheadfont{\fontsize{10}{13}\selectfont\fontseries{b}\selectfont} 1475 \def\addressfont{\hsize\abs@coli@hsize\ sffamily\fontsize{8}{11}\selectfont\leftskip\z@\rightskip\z@ plus1fil}%1476 \def\corresfont{\hsize\abs@coli@hsize\ sffamily\fontsize{8}{11}\selectfont\leftskip\z@\rightskip\z@ plus1fil}%1477 \def\FIfont{\hsize\abs@coli@hsize\ sffamily\fontsize{8}{11}\selectfont\leftskip\z@\rightskip\z@ plus1fil}%1478 \def\JELfont{\hsize\abs@coli@hsize\ sffamily\fontsize{8}{11}\selectfont\leftskip\z@\rightskip\z@ plus1fil}%1479 \def\keywordsheadfont{\hsize\abs@colii@hsize\ sffamily\fontsize{8}{8}\selectfont\ifAbstractexist\leftskip7\p@\rightskip\leftskip\fi}%1480 \def\abstractfont{\hsize\abs@colii@hsize\ sffamily\fontsize{9}{14}\selectfont\leftskip7\p@\rightskip\leftskip}%1481 \def\keywordsfont{\ sffamily\fontsize{8}{13}\selectfont\ifAbstractexist\leftskip7\p@\rightskip\leftskip\fi}%1475 \def\addressfont{\hsize\abs@coli@hsize\rmfamily\fontsize{8}{11}\selectfont\leftskip\z@\rightskip\z@ plus1fil}% 1476 \def\corresfont{\hsize\abs@coli@hsize\rmfamily\fontsize{8}{11}\selectfont\leftskip\z@\rightskip\z@ plus1fil}% 1477 \def\FIfont{\hsize\abs@coli@hsize\rmfamily\fontsize{8}{11}\selectfont\leftskip\z@\rightskip\z@ plus1fil}% 1478 \def\JELfont{\hsize\abs@coli@hsize\rmfamily\fontsize{8}{11}\selectfont\leftskip\z@\rightskip\z@ plus1fil}% 1479 \def\keywordsheadfont{\hsize\abs@colii@hsize\rmfamily\fontsize{8}{8}\selectfont\ifAbstractexist\leftskip7\p@\rightskip\leftskip\fi}% 1480 \def\abstractfont{\hsize\abs@colii@hsize\rmfamily\fontsize{10}{15}\selectfont\leftskip7\p@\rightskip\leftskip}% 1481 \def\keywordsfont{\rmfamily\fontsize{8}{13}\selectfont\ifAbstractexist\leftskip7\p@\rightskip\leftskip\fi}% 1482 1482 % 1483 1483 }% … … 1488 1488 % \def\watermarkfont{\reset@font\fontfamily{\ffdefault}\fontsize{45}{45}\bfseries\selectfont} 1489 1489 % 1490 \def\pagenumfont{\ sffamily\fontsize{7}{9}\bfseries\selectfont}%1491 \def\cnmpagenumfont{\ sffamily\fontsize{7}{9}\selectfont\bfseries}%1492 %%% \def\runningheadfont{\ sffamily\fontsize{7}{9}\scshape\selectfont}%1493 \def\runningheadfont{\ sffamily\fontsize{7}{9}\selectfont}%New updations 19aug20161494 \def\runningfootfont{\ sffamily\fontsize{7}{9}\selectfont}%1495 \def\titlepageheadfont{\ sffamily\fontsize{7}{9}\selectfont}%1490 \def\pagenumfont{\rmfamily\fontsize{7}{9}\bfseries\selectfont}% 1491 \def\cnmpagenumfont{\rmfamily\fontsize{7}{9}\selectfont\bfseries}% 1492 %%% \def\runningheadfont{\rmfamily\fontsize{7}{9}\scshape\selectfont}% 1493 \def\runningheadfont{\rmfamily\fontsize{7}{9}\selectfont}%New updations 19aug2016 1494 \def\runningfootfont{\rmfamily\fontsize{7}{9}\selectfont}% 1495 \def\titlepageheadfont{\rmfamily\fontsize{7}{9}\selectfont}% 1496 1496 % 1497 \def\BRarttypefont{\reset@font\ sffamily\fontsize{18}{18}\fontseries{b}\selectfont}%1498 \def\pubheadfont{\reset@font\ sffamily\fontsize{7}{9}\fontseries{b}\selectfont}%1499 \def\arttypefont{\ sffamily\fontsize{9}{9}\fontseries{b}\selectfont}%1500 \def\SParttypefont{\ sffamily\fontsize{9}{12}\fontseries{b}\selectfont}%1501 \def\titlefont{\ sffamily\fontsize{18}{23}\bfseries\selectfont\leftskip\z@\rightskip\z@ plus1fil\let\mathbcal\titmathbcal}%1502 \def\subtitlefont{\ sffamily\fontsize{16}{21}\bfseries\selectfont\leftskip\z@\rightskip\z@ plus1fil}%1503 \def\Authorfont{\ sffamily\fontsize{12}{18}\selectfont\bfseries\leftskip\z@\rightskip\z@ plus1fil}%1504 \def\addressfont{\hsize\abs@coli@hsize\ sffamily\fontsize{7}{10}\selectfont\leftskip\z@\rightskip\z@ plus1fil}%1505 \def\corresfont{\hsize\abs@coli@hsize\ sffamily\fontsize{7}{10}\selectfont\leftskip\z@\rightskip\z@ plus1fil}%1497 \def\BRarttypefont{\reset@font\rmfamily\fontsize{18}{18}\fontseries{b}\selectfont}% 1498 \def\pubheadfont{\reset@font\rmfamily\fontsize{7}{9}\fontseries{b}\selectfont}% 1499 \def\arttypefont{\rmfamily\fontsize{9}{9}\fontseries{b}\selectfont}% 1500 \def\SParttypefont{\rmfamily\fontsize{9}{12}\fontseries{b}\selectfont}% 1501 \def\titlefont{\rmfamily\fontsize{18}{23}\bfseries\selectfont\leftskip\z@\rightskip\z@ plus1fil\let\mathbcal\titmathbcal}% 1502 \def\subtitlefont{\rmfamily\fontsize{16}{21}\bfseries\selectfont\leftskip\z@\rightskip\z@ plus1fil}% 1503 \def\Authorfont{\rmfamily\fontsize{12}{18}\selectfont\bfseries\leftskip\z@\rightskip\z@ plus1fil}% 1504 \def\addressfont{\hsize\abs@coli@hsize\rmfamily\fontsize{7}{10}\selectfont\leftskip\z@\rightskip\z@ plus1fil}% 1505 \def\corresfont{\hsize\abs@coli@hsize\rmfamily\fontsize{7}{10}\selectfont\leftskip\z@\rightskip\z@ plus1fil}% 1506 1506 % 1507 \def\FIfont{\hsize\abs@coli@hsize\ sffamily\fontsize{7}{10}\selectfont\leftskip\z@\rightskip\z@ plus1fil}%1508 \def\JELfont{\hsize\abs@coli@hsize\ sffamily\fontsize{7}{10}\selectfont\leftskip\z@\rightskip\z@ plus1fil}%1509 \def\abstractfont{\hsize\abs@colii@hsize\ sffamily\fontsize{8}{13}\selectfont\leftskip7\p@\rightskip\leftskip}%1510 \def\keywordsheadfont{\hsize\abs@colii@hsize\ sffamily\fontsize{7}{7}\selectfont\ifAbstractexist\leftskip7\p@\rightskip\leftskip\fi}%1511 \def\absheadfont{\hsize\abs@colii@hsize\ sffamily\fontsize{10}{10}\fontseries{b}\selectfont\bfseries\leftskip7\p@\rightskip\leftskip}% LN20FEB20161512 \def\keywordsfont{\ sffamily\fontsize{8}{13}\selectfont\ifAbstractexist\leftskip7\p@\rightskip\leftskip\fi}%1513 \def\legalstatementfont{\ sffamily\fontsize{7}{10}\selectfont\leftskip0\p@\rightskip\leftskip}%1507 \def\FIfont{\hsize\abs@coli@hsize\rmfamily\fontsize{7}{10}\selectfont\leftskip\z@\rightskip\z@ plus1fil}% 1508 \def\JELfont{\hsize\abs@coli@hsize\rmfamily\fontsize{7}{10}\selectfont\leftskip\z@\rightskip\z@ plus1fil}% 1509 \def\abstractfont{\hsize\abs@colii@hsize\rmfamily\fontsize{8}{13}\selectfont\leftskip7\p@\rightskip\leftskip}% 1510 \def\keywordsheadfont{\hsize\abs@colii@hsize\rmfamily\fontsize{7}{7}\selectfont\ifAbstractexist\leftskip7\p@\rightskip\leftskip\fi}% 1511 \def\absheadfont{\hsize\abs@colii@hsize\rmfamily\fontsize{10}{10}\fontseries{b}\selectfont\bfseries\leftskip7\p@\rightskip\leftskip}% LN20FEB2016 1512 \def\keywordsfont{\rmfamily\fontsize{8}{13}\selectfont\ifAbstractexist\leftskip7\p@\rightskip\leftskip\fi}% 1513 \def\legalstatementfont{\rmfamily\fontsize{7}{10}\selectfont\leftskip0\p@\rightskip\leftskip}% 1514 1514 % 1515 \def\BRsectionfont{\ sffamily\fontsize{10}{16}\fontseries{b}\selectfont\leftskip\z@\rightskip\z@ plus1fil}%1516 \def\sectionfont{\ sffamily\fontsize{10}{13}\fontseries{b}\selectfont\leftskip\z@\rightskip\z@ plus1fil}%1517 \def\subsectionfont{\ sffamily\fontsize{10}{14}\bfseries\selectfont\leftskip\z@\rightskip\z@ plus1fil}%1518 \def\subsubsectionfont{\ sffamily\fontsize{9}{12.5}\bfseries\selectfont\leftskip\z@\rightskip\z@ plus1fil}%1519 \def\paragraphfont{\ sffamily\fontsize{8.5}{13}\fontseries{b}\selectfont}%1520 \def\subparagraphfont{\ sffamily\fontsize{8.5}{13}\fontseries{b}\selectfont}%1521 \def\appsectionfont{\ sffamily\fontsize{8}{11}\fontseries{b}\selectfont\leftskip\z@\rightskip\z@ plus1fil}%1515 \def\BRsectionfont{\rmfamily\fontsize{10}{16}\fontseries{b}\selectfont\leftskip\z@\rightskip\z@ plus1fil}% 1516 \def\sectionfont{\rmfamily\fontsize{10}{13}\fontseries{b}\selectfont\leftskip\z@\rightskip\z@ plus1fil}% 1517 \def\subsectionfont{\rmfamily\fontsize{10}{14}\bfseries\selectfont\leftskip\z@\rightskip\z@ plus1fil}% 1518 \def\subsubsectionfont{\rmfamily\fontsize{9}{12.5}\bfseries\selectfont\leftskip\z@\rightskip\z@ plus1fil}% 1519 \def\paragraphfont{\rmfamily\fontsize{8.5}{13}\fontseries{b}\selectfont}% 1520 \def\subparagraphfont{\rmfamily\fontsize{8.5}{13}\fontseries{b}\selectfont}% 1521 \def\appsectionfont{\rmfamily\fontsize{8}{11}\fontseries{b}\selectfont\leftskip\z@\rightskip\z@ plus1fil}% 1522 1522 % 1523 \def\boxheadfont{\ sffamily\fontsize{8}{10}\fontseries{b}\selectfont}1524 \def\boxtitlefont{\ sffamily\fontsize{8}{10}\bfseries\selectfont}1523 \def\boxheadfont{\rmfamily\fontsize{8}{10}\fontseries{b}\selectfont} 1524 \def\boxtitlefont{\rmfamily\fontsize{8}{10}\bfseries\selectfont} 1525 1525 % 1526 \def\GnSabsfont{\ sffamily\fontsize{9}{15}\selectfont}%1527 \def\GnSabsfootfont{\reset@font\ sffamily\fontsize{14}{0}\bfseries\selectfont}%1526 \def\GnSabsfont{\rmfamily\fontsize{9}{15}\selectfont}% 1527 \def\GnSabsfootfont{\reset@font\rmfamily\fontsize{14}{0}\bfseries\selectfont}% 1528 1528 % 1529 \def\suppinfofont{\noindent\ sffamily}%1529 \def\suppinfofont{\noindent\rmfamily}% 1530 1530 \def\suppinfoheadfont{\noindent\fontsize{8}{13}\fontseries{b}\selectfont}% 1531 \def\suppinfocaptionfont{\noindent\ sffamily}%1531 \def\suppinfocaptionfont{\noindent\rmfamily}% 1532 1532 % 1533 \def\figurenumfont{\ sffamily\fontsize{7bp}{9}\fontseries{b}\selectfont}%1534 \def\figurecaptionfont{\ sffamily\fontsize{8bp}{11}\selectfont}1533 \def\figurenumfont{\rmfamily\fontsize{7bp}{9}\fontseries{b}\selectfont}% 1534 \def\figurecaptionfont{\rmfamily\fontsize{8bp}{11}\selectfont} 1535 1535 \def\bwfiginfofont{\fontfamily{tim}\fontsize{10bp}{10bp}\selectfont}% 1536 1536 % 1537 \def\tablenumfont{\ sffamily\fontsize{7bp}{9bp}\fontseries{b}\selectfont}%1538 \def\keypointheadfont{\reset@font\ sffamily\fontsize{9bp}{11bp}\fontseries{b}\selectfont}%1539 \def\tablecaptionfont{\ sffamily\fontsize{8bp}{9bp}\selectfont}1540 \def\tablebodyfont{\ sffamily\fontsize{7.5bp}{9bp}\selectfont}1541 \def\tablecolheadfont{\ sffamily\fontsize{7.5bp}{9bp}\selectfont\bfseries}1542 \def\tablefootnotefont{\ sffamily\fontsize{7.5bp}{9bp}\selectfont}1537 \def\tablenumfont{\rmfamily\fontsize{7bp}{9bp}\fontseries{b}\selectfont}% 1538 \def\keypointheadfont{\reset@font\rmfamily\fontsize{9bp}{11bp}\fontseries{b}\selectfont}% 1539 \def\tablecaptionfont{\rmfamily\fontsize{8bp}{9bp}\selectfont} 1540 \def\tablebodyfont{\rmfamily\fontsize{7.5bp}{9bp}\selectfont} 1541 \def\tablecolheadfont{\rmfamily\fontsize{7.5bp}{9bp}\selectfont\bfseries} 1542 \def\tablefootnotefont{\rmfamily\fontsize{7.5bp}{9bp}\selectfont} 1543 1543 % 1544 %% \def\footnotetextfont{\ sffamily\fontsize{8bp}{10bp}\selectfont}1544 %% \def\footnotetextfont{\rmfamily\fontsize{8bp}{10bp}\selectfont} 1545 1545 % 1546 1546 \def\listfont{\normalsize}% -
doc/papers/concurrency/Paper.tex
ra0c7d5cc r534d84e 22 22 \captionsetup{justification=raggedright,singlelinecheck=false} 23 23 \usepackage{siunitx} 24 \sisetup{ binary-units=true}24 \sisetup{binary-units=true} 25 25 26 26 \hypersetup{breaklinks=true} … … 32 32 \renewcommand{\linenumberfont}{\scriptsize\sffamily} 33 33 34 \renewcommand{\textfraction}{0.0} % the entire page maybe devoted to floats with no text on the page at all34 \renewcommand{\textfraction}{0.0} % the entire page maybe devoted to floats with no text on the page at all 35 35 36 36 \lefthyphenmin=3 % hyphen only after 4 characters … … 70 70 %\DeclareTextCommandDefault{\textunderscore}{\leavevmode\makebox[1.2ex][c]{\rule{1ex}{0.1ex}}} 71 71 \renewcommand{\textunderscore}{\leavevmode\makebox[1.2ex][c]{\rule{1ex}{0.075ex}}} 72 %\def\myCHarFont{\fontencoding{T1}\selectfont}% 73 % \def\{{\ttfamily\upshape\myCHarFont \char`\}}}% 72 74 73 75 \makeatletter … … 244 246 \maketitle 245 247 246 % ====================================================================== 247 % ====================================================================== 248 248 249 \section{Introduction} 249 % ======================================================================250 % ======================================================================251 250 252 251 This paper provides a minimal concurrency \newterm{Abstract Program Interface} (API) that is simple, efficient and can be used to build other concurrency features. … … 254 253 An easier approach for programmers is to support higher-level constructs as the basis of concurrency. 255 254 Indeed, for highly productive concurrent programming, high-level approaches are much more popular~\cite{Hochstein05}. 256 Examples of high-level approaches are task based~\cite{TBB}, message passing~\cite{Erlang,MPI}, and implicit threading~\cite{OpenMP}.255 Examples of high-level approaches are task (work) based~\cite{TBB}, implicit threading~\cite{OpenMP}, monitors~\cite{Java}, channels~\cite{CSP,Go}, and message passing~\cite{Erlang,MPI}. 257 256 258 257 This paper uses the following terminology. … … 272 271 The paper discusses how the language features are added to the \CFA translator with respect to parsing, semantic, and type checking, and the corresponding high-perforamnce runtime-library to implement the concurrency features. 273 272 274 % ====================================================================== 275 % ====================================================================== 273 276 274 \section{\CFA Overview} 277 % ======================================================================278 % ======================================================================279 275 280 276 The following is a quick introduction to the \CFA language, specifically tailored to the features needed to support concurrency. 281 Most of the following code examples can be found on the \CFA website~\cite{Cforall}.282 283 \CFA is an extension of ISO-C, and therefore, supports all of the same paradigms as C.277 Extended versions of the following code examples are available at the \CFA website~\cite{Cforall} or Moss~\etal~\cite{XXX}. 278 279 \CFA is an extension of ISO-C, and hence, supports all C paradigms. 284 280 %It is a non-object-oriented system-language, meaning most of the major abstractions have either no runtime overhead or can be opted out easily. 285 Like C, the basics of \CFA revolve around structures and routines, which are thin abstractions over machine code. 286 The vast majority of the code produced by the \CFA translator respects memory layouts and calling conventions laid out by C. 287 Interestingly, while \CFA is not an object-oriented language, lacking the concept of a receiver (\eg @this@) and inheritance, it does have some notion of objects\footnote{C defines the term objects as : ``region of data storage in the execution environment, the contents of which can represent 288 values''~\cite[3.15]{C11}}, most importantly construction and destruction of objects. 281 Like C, the basics of \CFA revolve around structures and functions. 282 Virtually all of the code generated by the \CFA translator respects C memory layouts and calling conventions. 283 While \CFA is not an object-oriented language, lacking the concept of a receiver (\eg @this@) and nominal inheritance-relationships, C does have a notion of objects: ``region of data storage in the execution environment, the contents of which can represent values''~\cite[3.15]{C11}. 289 284 290 285 291 286 \subsection{References} 292 287 293 Like \CC, \CFA introduces rebind-able references providing multiple dereferencing as an alternative to pointers. 294 In regards to concurrency, the semantic difference between pointers and references are not particularly relevant, but since this document uses mostly references, here is a quick overview of the semantics: 295 \begin{cfa} 296 int x, y, z; 297 int * p1 = &x, ** p2 = &p1, *** p3 = &p2, $\C{// pointers to x}$ 298 & r1 = x, && r2 = r1, &&& r3 = r2; $\C{// references to x}$ 299 300 *p1 = 3; **p2 = 3; ***p3 = 3; $\C{// change x}$ 301 r1 = 3; r2 = 3; r3 = 3; $\C{// change x}$ 302 **p3 = &y; *p3 = &z; $\C{// change p1, p2}$ 303 &&r3 = &y; &r3 = &z; $\C{// change p1, p2}$ 304 int & ar[3] = {x, y, z}; $\C{// initialize array of references}$ 305 306 typeof( ar[1]) p; $\C{// is int, referenced object type}$ 307 typeof(&ar[1]) q; $\C{// is int \&, reference type}$ 308 sizeof( ar[1]) == sizeof(int); $\C{// is true, referenced object size}$ 309 sizeof(&ar[1]) == sizeof(int *); $\C{// is true, reference size}$ 310 \end{cfa} 311 The important take away from this code example is that a reference offers a handle to an object, much like a pointer, but which is automatically dereferenced for convenience. 312 313 % ====================================================================== 288 \CFA provides multi-level rebindable references, as an alternative to pointers, which significantly reduces syntactic noise. 289 \begin{cfa} 290 int x = 1, y = 2, z = 3; 291 int * p1 = &x, ** p2 = &p1, *** p3 = &p2, $\C{// pointers to x}$ 292 `&` r1 = x, `&&` r2 = r1, `&&&` r3 = r2; $\C{// references to x}$ 293 int * p4 = &z, `&` r4 = z; 294 295 *p1 = 3; **p2 = 3; ***p3 = 3; // change x 296 r1 = 3; r2 = 3; r3 = 3; // change x: implicit dereferences *r1, **r2, ***r3 297 **p3 = &y; *p3 = &p4; // change p1, p2 298 `&`r3 = &y; `&&`r3 = &`&`r4; // change r1, r2: cancel implicit deferences (&*)**r3, (&(&*)*)*r3, &(&*)r4 299 \end{cfa} 300 A reference is a handle to an object, like a pointer, but is automatically dereferenced the specified number of levels. 301 Referencing (address-of @&@) a reference variable cancels one of the implicit dereferences, until there are no more implicit references, after which normal expression behaviour applies. 302 303 304 \subsection{\texorpdfstring{\protect\lstinline{with} Statement}{with Statement}} 305 \label{s:WithStatement} 306 307 Heterogeneous data is often aggregated into a structure/union. 308 To reduce syntactic noise, \CFA provides a @with@ statement (see Pascal~\cite[\S~4.F]{Pascal}) to elide aggregate field-qualification by opening a scope containing the field identifiers. 309 \begin{cquote} 310 \vspace*{-\baselineskip}%??? 311 \lstDeleteShortInline@% 312 \begin{cfa} 313 struct S { char c; int i; double d; }; 314 struct T { double m, n; }; 315 // multiple aggregate parameters 316 \end{cfa} 317 \begin{tabular}{@{}l@{\hspace{\parindentlnth}}|@{\hspace{\parindentlnth}}l@{}} 318 \begin{cfa} 319 void f( S & s, T & t ) { 320 `s.`c; `s.`i; `s.`d; 321 `t.`m; `t.`n; 322 } 323 \end{cfa} 324 & 325 \begin{cfa} 326 void f( S & s, T & t ) `with ( s, t )` { 327 c; i; d; // no qualification 328 m; n; 329 } 330 \end{cfa} 331 \end{tabular} 332 \lstMakeShortInline@% 333 \end{cquote} 334 Object-oriented programming languages only provide implicit qualification for the receiver. 335 336 In detail, the @with@ statement has the form: 337 \begin{cfa} 338 $\emph{with-statement}$: 339 'with' '(' $\emph{expression-list}$ ')' $\emph{compound-statement}$ 340 \end{cfa} 341 and may appear as the body of a function or nested within a function body. 342 Each expression in the expression-list provides a type and object. 343 The type must be an aggregate type. 344 (Enumerations are already opened.) 345 The object is the implicit qualifier for the open structure-fields. 346 All expressions in the expression list are open in parallel within the compound statement, which is different from Pascal, which nests the openings from left to right. 347 348 314 349 \subsection{Overloading} 315 350 316 Another important feature of \CFA is function overloading as in Java and \CC, where routines with the same name are selected based on the number and type of the arguments. 317 As well, \CFA uses the return type as part of the selection criteria, as in Ada~\cite{Ada}. 318 For routines with multiple parameters and returns, the selection is complex. 351 \CFA maximizes the ability to reuse names via overloading to aggressively address the naming problem. 352 Both variables and functions may be overloaded, where selection is based on types, and number of returns (as in Ada~\cite{Ada}) and arguments. 353 \begin{cquote} 354 \vspace*{-\baselineskip}%??? 355 \lstDeleteShortInline@% 356 \begin{cfa} 357 // selection based on type 358 \end{cfa} 359 \begin{tabular}{@{}l@{\hspace{\parindentlnth}}|@{\hspace{\parindentlnth}}l@{}} 360 \begin{cfa} 361 const short int MIN = -32768; 362 const int MIN = -2147483648; 363 const long int MIN = -9223372036854775808L; 364 \end{cfa} 365 & 366 \begin{cfa} 367 short int si = MIN; 368 int i = MIN; 369 long int li = MIN; 370 \end{cfa} 371 \end{tabular} 319 372 \begin{cfa} 320 373 // selection based on type and number of parameters 321 void f(void); $\C{// (1)}$ 322 void f(char); $\C{// (2)}$ 323 void f(int, double); $\C{// (3)}$ 324 f(); $\C{// select (1)}$ 325 f('a'); $\C{// select (2)}$ 326 f(3, 5.2); $\C{// select (3)}$ 327 328 // selection based on type and number of returns 329 char f(int); $\C{// (1)}$ 330 double f(int); $\C{// (2)}$ 331 char c = f(3); $\C{// select (1)}$ 332 double d = f(4); $\C{// select (2)}$ 333 \end{cfa} 334 This feature is particularly important for concurrency since the runtime system relies on creating different types to represent concurrency objects. 374 \end{cfa} 375 \begin{tabular}{@{}l@{\hspace{1.7\parindentlnth}}|@{\hspace{\parindentlnth}}l@{}} 376 \begin{cfa} 377 void f( void ); 378 void f( char ); 379 void f( int, double ); 380 \end{cfa} 381 & 382 \begin{cfa} 383 f(); 384 f( 'a' ); 385 f( 3, 5.2 ); 386 \end{cfa} 387 \end{tabular} 388 \begin{cfa} 389 // selection based on type and number of returns 390 \end{cfa} 391 \begin{tabular}{@{}l@{\hspace{\parindentlnth}}|@{\hspace{\parindentlnth}}l@{}} 392 \begin{cfa} 393 char f( int ); 394 double f( int ); 395 [char, double] f( int ); 396 \end{cfa} 397 & 398 \begin{cfa} 399 char c = f( 3 ); 400 double d = f( 3 ); 401 [d, c] = f( 3 ); 402 \end{cfa} 403 \end{tabular} 404 \lstMakeShortInline@% 405 \end{cquote} 406 Overloading is important for \CFA concurrency since the runtime system relies on creating different types to represent concurrency objects. 335 407 Therefore, overloading is necessary to prevent the need for long prefixes and other naming conventions that prevent name clashes. 336 As seen in section \ref{basics}, routine @main@ is an example that benefits from overloading. 337 338 % ====================================================================== 408 As seen in Section~\ref{basics}, function @main@ is heavily overloaded. 409 410 Variable overloading is useful in the parallel semantics of the @with@ statement for fields with the same name: 411 \begin{cfa} 412 struct S { int `i`; int j; double m; } s; 413 struct T { int `i`; int k; int m; } t; 414 with ( s, t ) { 415 j + k; $\C{// unambiguous, s.j + t.k}$ 416 m = 5.0; $\C{// unambiguous, t.m = 5.0}$ 417 m = 1; $\C{// unambiguous, s.m = 1}$ 418 int a = m; $\C{// unambiguous, a = s.i }$ 419 double b = m; $\C{// unambiguous, b = t.m}$ 420 int c = `s.i` + `t.i`; $\C{// unambiguous, qualification}$ 421 (double)m; $\C{// unambiguous, cast}$ 422 } 423 \end{cfa} 424 For parallel semantics, both @s.i@ and @t.i@ are visible with the same type, so only @i@ is ambiguous without qualification. 425 426 339 427 \subsection{Operators} 428 340 429 Overloading also extends to operators. 341 The syntax for denoting operator-overloading is to name a routine with the symbol of the operator and question marks where the arguments of the operation appear, \eg: 342 \begin{cfa} 343 int ++? (int op); $\C{// unary prefix increment}$ 344 int ?++ (int op); $\C{// unary postfix increment}$ 345 int ?+? (int op1, int op2); $\C{// binary plus}$ 346 int ?<=?(int op1, int op2); $\C{// binary less than}$ 347 int ?=? (int & op1, int op2); $\C{// binary assignment}$ 348 int ?+=?(int & op1, int op2); $\C{// binary plus-assignment}$ 349 350 struct S {int i, j;}; 351 S ?+?(S op1, S op2) { $\C{// add two structures}$ 430 Operator-overloading syntax names a routine with the operator symbol and question marks for the operands: 431 \begin{cquote} 432 \lstDeleteShortInline@% 433 \begin{tabular}{@{}ll@{\hspace{\parindentlnth}}|@{\hspace{\parindentlnth}}l@{}} 434 \begin{cfa} 435 int ++? (int op); 436 int ?++ (int op); 437 int `?+?` (int op1, int op2); 438 int ?<=?(int op1, int op2); 439 int ?=? (int & op1, int op2); 440 int ?+=?(int & op1, int op2); 441 \end{cfa} 442 & 443 \begin{cfa} 444 // unary prefix increment 445 // unary postfix increment 446 // binary plus 447 // binary less than 448 // binary assignment 449 // binary plus-assignment 450 \end{cfa} 451 & 452 \begin{cfa} 453 struct S { int i, j; }; 454 S `?+?`( S op1, S op2) { // add two structures 352 455 return (S){op1.i + op2.i, op1.j + op2.j}; 353 456 } 354 457 S s1 = {1, 2}, s2 = {2, 3}, s3; 355 s3 = s1 + s2; $\C{// compute sum: s3 == {2, 5}}$ 356 \end{cfa} 357 While concurrency does not use operator overloading directly, this feature is more important as an introduction for the syntax of constructors. 358 359 % ====================================================================== 360 \subsection{Constructors/Destructors} 361 Object lifetime is often a challenge in concurrency. \CFA uses the approach of giving concurrent meaning to object lifetime as a means of synchronization and/or mutual exclusion. 362 Since \CFA relies heavily on the lifetime of objects, constructors and destructors is a core feature required for concurrency and parallelism. \CFA uses the following syntax for constructors and destructors: 363 \begin{cfa} 364 struct S { 365 size_t size; 366 int * ia; 367 }; 368 void ?{}(S & s, int asize) { $\C{// constructor operator}$ 369 s.size = asize; $\C{// initialize fields}$ 370 s.ia = calloc(size, sizeof(S)); 371 } 372 void ^?{}(S & s) { $\C{// destructor operator}$ 373 free(ia); $\C{// de-initialization fields}$ 374 } 375 int main() { 376 S x = {10}, y = {100}; $\C{// implicit calls: ?\{\}(x, 10), ?\{\}(y, 100)}$ 377 ... $\C{// use x and y}$ 378 ^x{}; ^y{}; $\C{// explicit calls to de-initialize}$ 379 x{20}; y{200}; $\C{// explicit calls to reinitialize}$ 380 ... $\C{// reuse x and y}$ 381 } $\C{// implicit calls: \^?\{\}(y), \^?\{\}(x)}$ 382 \end{cfa} 383 The language guarantees that every object and all their fields are constructed. 384 Like \CC, construction of an object is automatically done on allocation and destruction of the object is done on deallocation. 385 Allocation and deallocation can occur on the stack or on the heap. 386 \begin{cfa} 387 { 388 struct S s = {10}; $\C{// allocation, call constructor}$ 389 ... 390 } $\C{// deallocation, call destructor}$ 391 struct S * s = new(); $\C{// allocation, call constructor}$ 392 ... 393 delete(s); $\C{// deallocation, call destructor}$ 394 \end{cfa} 395 Note that like \CC, \CFA introduces @new@ and @delete@, which behave like @malloc@ and @free@ in addition to constructing and destructing objects, after calling @malloc@ and before calling @free@, respectively. 396 397 % ====================================================================== 458 s3 = s1 `+` s2; // compute sum: s3 == {2, 5} 459 \end{cfa} 460 \end{tabular} 461 \lstMakeShortInline@% 462 \end{cquote} 463 While concurrency does not use operator overloading directly, it provides an introduction for the syntax of constructors. 464 465 398 466 \subsection{Parametric Polymorphism} 399 467 \label{s:ParametricPolymorphism} 400 Routines in \CFA can also be reused for multiple types. 401 Th is capability is done using the @forall@ clauses, which allow separately compiled routines to support generic usage over multiple types.468 469 The signature feature of \CFA is parametric-polymorphic functions~\cite{} with functions generalized using a @forall@ clause (giving the language its name), which allow separately compiled routines to support generic usage over multiple types. 402 470 For example, the following sum function works for any type that supports construction from 0 and addition: 403 471 \begin{cfa} 404 // constraint type, 0 and + 405 forall(otype T | { void ?{}(T *, zero_t); T ?+?(T, T); }) 406 T sum(T a[ ], size_t size) { 407 T total = 0; $\C{// construct T from 0}$ 408 for(size_t i = 0; i < size; i++) 409 total = total + a[i]; $\C{// select appropriate +}$ 472 forall( otype T | { void `?{}`( T *, zero_t ); T `?+?`( T, T ); } ) // constraint type, 0 and + 473 T sum( T a[$\,$], size_t size ) { 474 `T` total = { `0` }; $\C{// initialize by 0 constructor}$ 475 for ( size_t i = 0; i < size; i += 1 ) 476 total = total `+` a[i]; $\C{// select appropriate +}$ 410 477 return total; 411 478 } 412 413 479 S sa[5]; 414 int i = sum(sa, 5); $\C{// use S's 0 construction and +}$ 415 \end{cfa} 416 417 Since writing constraints on types can become cumbersome for more constrained functions, \CFA also has the concept of traits. 418 Traits are named collection of constraints that can be used both instead and in addition to regular constraints: 419 \begin{cfa} 420 trait summable( otype T ) { 421 void ?{}(T *, zero_t); $\C{// constructor from 0 literal}$ 422 T ?+?(T, T); $\C{// assortment of additions}$ 423 T ?+=?(T *, T); 424 T ++?(T *); 425 T ?++(T *); 480 int i = sum( sa, 5 ); $\C{// use S's 0 construction and +}$ 481 \end{cfa} 482 483 \CFA provides \newterm{traits} to name a group of type assertions, where the trait name allows specifying the same set of assertions in multiple locations, preventing repetition mistakes at each function declaration: 484 \begin{cfa} 485 trait `sumable`( otype T ) { 486 void `?{}`( T &, zero_t ); $\C{// 0 literal constructor}$ 487 T `?+?`( T, T ); $\C{// assortment of additions}$ 488 T ?+=?( T &, T ); 489 T ++?( T & ); 490 T ?++( T & ); 426 491 }; 427 forall( otype T | summable(T) ) $\C{// use trait}$ 428 T sum(T a[], size_t size); 429 \end{cfa} 430 431 Note that the type use for assertions can be either an @otype@ or a @dtype@. 432 Types declared as @otype@ refer to ``complete'' objects, \ie objects with a size, a default constructor, a copy constructor, a destructor and an assignment operator. 433 Using @dtype@, on the other hand, has none of these assumptions but is extremely restrictive, it only guarantees the object is addressable. 434 435 % ====================================================================== 436 \subsection{with Clause/Statement} 437 Since \CFA lacks the concept of a receiver, certain functions end up needing to repeat variable names often. 438 To remove this inconvenience, \CFA provides the @with@ statement, which opens an aggregate scope making its fields directly accessible (like Pascal). 439 \begin{cfa} 440 struct S { int i, j; }; 441 int mem(S & this) with (this) $\C{// with clause}$ 442 i = 1; $\C{// this->i}$ 443 j = 2; $\C{// this->j}$ 444 } 445 int foo() { 446 struct S1 { ... } s1; 447 struct S2 { ... } s2; 448 with (s1) $\C{// with statement}$ 449 { 450 // access fields of s1 without qualification 451 with (s2) $\C{// nesting}$ 452 { 453 // access fields of s1 and s2 without qualification 454 } 455 } 456 with (s1, s2) $\C{// scopes open in parallel}$ 457 { 458 // access fields of s1 and s2 without qualification 459 } 460 } 461 \end{cfa} 462 463 For more information on \CFA see \cite{cforall-ug,Schluntz17,www-cfa}. 464 465 % ====================================================================== 466 % ====================================================================== 492 forall( otype T `| sumable( T )` ) $\C{// use trait}$ 493 T sum( T a[$\,$], size_t size ); 494 \end{cfa} 495 496 Assertions can be @otype@ or @dtype@. 497 @otype@ refers to a ``complete'' object, \ie an object has a size, default constructor, copy constructor, destructor and an assignment operator. 498 @dtype@ only guarantees an object has a size and alignment. 499 500 Using the return type for discrimination, it is possible to write a type-safe @alloc@ based on the C @malloc@: 501 \begin{cfa} 502 forall( dtype T | sized(T) ) T * alloc( void ) { return (T *)malloc( sizeof(T) ); } 503 int * ip = alloc(); $\C{// select type and size from left-hand side}$ 504 double * dp = alloc(); 505 struct S {...} * sp = alloc(); 506 \end{cfa} 507 where the return type supplies the type/size of the allocation, which is impossible in most type systems. 508 509 510 \subsection{Constructors / Destructors} 511 512 Object lifetime is a challenge in non-managed programming languages. 513 \CFA responds with \CC-like constructors and destructors: 514 \begin{cfa} 515 struct VLA { int len, * data; }; $\C{// variable length array of integers}$ 516 void ?{}( VLA & vla ) with ( vla ) { len = 10; data = alloc( len ); } // default constructor 517 void ?{}( VLA & vla, int size, char fill ) with ( vla ) { len = size; data = alloc( len, fill ); } // initialization 518 void ?{}( VLA & vla, VLA other ) { vla.len = other.len; vla.data = other.data; } // copy, shallow 519 void ^?{}( VLA & vla ) with ( vla ) { free( data ); } $\C{// destructor}$ 520 { 521 VLA x, y = { 20, 0x01 }, z = y; $\C{// z points to y}$ 522 // ?{}( x ); ?{}( y, 20, 0x01 ); ?{}( z, y ); 523 ^x{}; $\C{// deallocate x}$ 524 x{}; $\C{// reallocate x}$ 525 z{ 5, 0xff }; $\C{// reallocate z, not pointing to y}$ 526 ^y{}; $\C{// deallocate y}$ 527 y{ x }; $\C{// reallocate y, points to x}$ 528 x{}; $\C{// reallocate x, not pointing to y}$ 529 // ^?{}(z); ^?{}(y); ^?{}(x); 530 } 531 \end{cfa} 532 Like \CC, construction is implicit on allocation (stack/heap) and destruction is implicit on deallocation. 533 The object and all their fields are constructed/destructed. 534 \CFA also provides @new@ and @delete@, which behave like @malloc@ and @free@, in addition to constructing and destructing objects: 535 \begin{cfa} 536 { struct S s = {10}; $\C{// allocation, call constructor}$ 537 ... 538 } $\C{// deallocation, call destructor}$ 539 struct S * s = new(); $\C{// allocation, call constructor}$ 540 ... 541 delete( s ); $\C{// deallocation, call destructor}$ 542 \end{cfa} 543 \CFA concurrency uses object lifetime as a means of synchronization and/or mutual exclusion. 544 545 467 546 \section{Concurrency Basics}\label{basics} 468 % ====================================================================== 469 % ====================================================================== 470 471 At its core, concurrency is based on having multiple call-stacks and scheduling among threads of execution executing on these stacks. 547 548 At its core, concurrency is based on multiple call-stacks and scheduling among threads executing on these stacks. 472 549 Multiple call stacks (or contexts) and a single thread of execution does \emph{not} imply concurrency. 473 550 Execution with a single thread and multiple stacks where the thread is deterministically self-scheduling across the stacks is called \newterm{coroutining}; … … 585 662 \begin{lstlisting}[aboveskip=0pt,belowskip=0pt] 586 663 `coroutine` Fib { int fn; }; 664 void ?{}( Fibonacci & fib ) with( fib ) { fn = 0; } 587 665 void main( Fib & f ) with( f ) { 588 666 int f1, f2; -
doc/papers/general/Paper.tex
ra0c7d5cc r534d84e 74 74 \setlength{\gcolumnposn}{3.5in} 75 75 \setlength{\columnposn}{\gcolumnposn} 76 76 77 \newcommand{\C}[2][\@empty]{\ifx#1\@empty\else\global\setlength{\columnposn}{#1}\global\columnposn=\columnposn\fi\hfill\makebox[\textwidth-\columnposn][l]{\lst@basicstyle{\LstCommentStyle{#2}}}} 77 78 \newcommand{\CRT}{\global\columnposn=\gcolumnposn} … … 191 192 This installation base and the programmers producing it represent a massive software-engineering investment spanning decades and likely to continue for decades more. 192 193 Nevertheless, C, first standardized over thirty years ago, lacks many features that make programming in more modern languages safer and more productive. 193 194 194 The goal of the \CFA project is to create an extension of C that provides modern safety and productivity features while still ensuring strong backwards compatibility with C and its programmers. 195 195 Prior projects have attempted similar goals but failed to honour C programming-style; for instance, adding object-oriented or functional programming with garbage collection is a non-starter for many C developers. … … 209 209 210 210 \section{Introduction} 211 212 211 The C programming language is a foundational technology for modern computing with millions of lines of code implementing everything from commercial operating-systems to hobby projects. 213 212 This installation base and the programmers producing it represent a massive software-engineering investment spanning decades and likely to continue for decades more. … … 238 237 \CC is used similarly, but has the disadvantages of multiple legacy design-choices that cannot be updated and active divergence of the language model from C, requiring significant effort and training to incrementally add \CC to a C-based project. 239 238 240 \CFA is currently implemented as asource-to-source translator from \CFA to the gcc-dialect of C~\cite{GCCExtensions}, allowing it to leverage the portability and code optimizations provided by gcc, meeting goals (1)--(3).239 \CFA is an \emph{open-source} project implemented as an source-to-source translator from \CFA to the gcc-dialect of C~\cite{GCCExtensions}, allowing it to leverage the portability and code optimizations provided by gcc, meeting goals (1)--(3). 241 240 Ultimately, a compiler is necessary for advanced features and optimal performance. 242 241 All features discussed in this paper are working, unless otherwise stated as under construction. … … 266 265 Code generation for these overloaded functions and variables is implemented by the usual approach of mangling the identifier names to include a representation of their type, while \CFA decides which overload to apply based on the same ``usual arithmetic conversions'' used in C to disambiguate operator overloads. 267 266 As an example: 268 269 \begin{cfa} 270 int max = 2147483647; $\C[4in]{// (1)}$ 271 double max = 1.7976931348623157E+308; $\C{// (2)}$ 267 \begin{cfa} 268 int max = 2147483647; $\C[4in]{// (1)}$ 269 double max = 1.7976931348623157E+308; $\C{// (2)}$ 272 270 int max( int a, int b ) { return a < b ? b : a; } $\C{// (3)}$ 273 271 double max( double a, double b ) { return a < b ? b : a; } $\C{// (4)}\CRT$ … … 329 327 A simple example is leveraging the existing type-unsafe (@void *@) C @bsearch@ to binary search a sorted float array: 330 328 \begin{cfa} 331 void * bsearch( const void * key, const void * base, size_t nmemb, size_t size, int (* compar)( const void *, const void * )); 329 void * bsearch( const void * key, const void * base, size_t nmemb, size_t size, 330 int (* compar)( const void *, const void * )); 332 331 int comp( const void * t1, const void * t2 ) { 333 332 return *(double *)t1 < *(double *)t2 ? -1 : *(double *)t2 < *(double *)t1 ? 1 : 0; … … 377 376 Hence, programmers can easily form local environments, adding and modifying appropriate functions, to maximize reuse of other existing functions and types. 378 377 379 Under construction is a mechanism to distribute @forall@ over routines/types, where each block declaration is prefixed with the initial @forall@ clause significantly reducing duplication (see @stack@ examples in Section~\ref{sec:eval}): 380 \begin{cfa} 381 forall( otype `T` ) { $\C{// forall block}$378 To reducing duplication, it is possible to distribute a group of @forall@ (and storage-class qualifiers) over functions/types, so each block declaration is prefixed by the group (see example in Appendix~\ref{s:CforallStack}). 379 \begin{cfa} 380 forall( otype `T` ) { $\C{// distribution block, add forall qualifier to declarations}$ 382 381 struct stack { stack_node(`T`) * head; }; $\C{// generic type}$ 383 void push( stack(`T`) & s, `T` value ) ... $\C{// generic operations}$ 384 T pop( stack(`T`) & s ) ... 382 inline { $\C{// nested distribution block, add forall/inline to declarations}$ 383 void push( stack(`T`) & s, `T` value ) ... $\C{// generic operations}$ 384 T pop( stack(`T`) & s ) ... 385 } 385 386 } 386 387 \end{cfa} … … 390 391 391 392 \CFA provides \newterm{traits} to name a group of type assertions, where the trait name allows specifying the same set of assertions in multiple locations, preventing repetition mistakes at each function declaration: 392 \begin{cfa} 393 trait `summable`( otype T ) { 394 void ?{}( T *, zero_t ); $\C{// constructor from 0 literal}$ 395 T ?+?( T, T ); $\C{// assortment of additions}$ 396 T ?+=?( T *, T ); 397 T ++?( T * ); 398 T ?++( T * ); 393 \begin{cquote} 394 \lstDeleteShortInline@% 395 \begin{tabular}{@{}l@{\hspace{\parindentlnth}}|@{\hspace{\parindentlnth}}l@{}} 396 \begin{cfa} 397 trait `sumable`( otype T ) { 398 void `?{}`( T &, zero_t ); // 0 literal constructor 399 T ?+?( T, T ); // assortment of additions 400 T `?+=?`( T &, T ); 401 T ++?( T & ); 402 T ?++( T & ); 399 403 }; 400 forall( otype T `| summable( T )` ) T sum( T a[$\,$], size_t size ) {$\C{// use trait}$ 401 `T` total = { `0` }; $\C{// instantiate T from 0 by calling its constructor}$ 402 for ( unsigned int i = 0; i < size; i += 1 ) total `+=` a[i]; $\C{// select appropriate +}$ 404 \end{cfa} 405 & 406 \begin{cfa} 407 forall( otype T `| sumable( T )` ) // use trait 408 T sum( T a[$\,$], size_t size ) { 409 `T` total = { `0` }; // initialize by 0 constructor 410 for ( size_t i = 0; i < size; i += 1 ) 411 total `+=` a[i]; // select appropriate + 403 412 return total; 404 413 } 405 414 \end{cfa} 415 \end{tabular} 416 \lstMakeShortInline@% 417 \end{cquote} 406 418 407 419 In fact, the set of @summable@ trait operators is incomplete, as it is missing assignment for type @T@, but @otype@ is syntactic sugar for the following implicit trait: … … 466 478 467 479 A generic type can be declared by placing a @forall@ specifier on a @struct@ or @union@ declaration, and instantiated using a parenthesized list of types after the type name: 480 \begin{cquote} 481 \lstDeleteShortInline@% 482 \begin{tabular}{@{}l@{\hspace{2\parindentlnth}}l@{}} 468 483 \begin{cfa} 469 484 forall( otype R, otype S ) struct pair { 470 R first; 471 S second; 485 R first; S second; 472 486 }; 473 forall( otype T ) T value( pair( const char *, T ) p ) { return p.second; } $\C{// dynamic}$ 474 forall( dtype F, otype T ) T value( pair( F *, T * ) p ) { return *p.second; } $\C{// dtype-static (concrete)}$ 475 476 pair( const char *, int ) p = { "magic", 42 }; $\C{// concrete}$ 487 `forall( otype T )` // dynamic 488 T value( pair(const char *, T) p ) { return p.second; } 489 `forall( dtype F, otype T )` // dtype-static (concrete) 490 T value( pair(F *, T * ) p) { return *p.second; } 491 \end{cfa} 492 & 493 \begin{cfa} 494 pair(const char *, int) p = {"magic", 42}; // concrete 477 495 int i = value( p ); 478 pair( void *, int * ) q = { 0, &p.second }; $\C{// concrete}$496 pair(void *, int *) q = { 0, &p.second }; // concrete 479 497 i = value( q ); 480 498 double d = 1.0; 481 pair( double *, double * ) r = { &d, &d }; $\C{// concrete}$499 pair(double *, double *) r = { &d, &d }; // concrete 482 500 d = value( r ); 483 501 \end{cfa} 502 \end{tabular} 503 \lstMakeShortInline@% 504 \end{cquote} 484 505 485 506 \CFA classifies generic types as either \newterm{concrete} or \newterm{dynamic}. … … 568 589 Another useful pattern enabled by reused dtype-static type instantiations is zero-cost \newterm{tag-structures}. 569 590 Sometimes information is only used for type-checking and can be omitted at runtime, \eg: 591 \begin{cquote} 592 \lstDeleteShortInline@% 593 \begin{tabular}{@{}l@{\hspace{2\parindentlnth}}l@{}} 570 594 \begin{cfa} 571 595 forall( dtype Unit ) struct scalar { unsigned long value; }; 572 596 struct metres {}; 573 597 struct litres {}; 574 575 598 forall( dtype U ) scalar(U) ?+?( scalar(U) a, scalar(U) b ) { 576 599 return (scalar(U)){ a.value + b.value }; 577 600 } 578 scalar(metres) half_marathon = { 21_093 }; 579 scalar(litres) swimming_pool = { 2_500_000 }; 580 scalar(metres) marathon = half_marathon + half_marathon; 581 scalar(litres) two_pools = swimming_pool + swimming_pool; 582 marathon + swimming_pool; $\C{// compilation ERROR}$ 583 \end{cfa} 601 \end{cfa} 602 & 603 \begin{cfa} 604 scalar(metres) half_marathon = { 21_098 }; 605 scalar(litres) pool = { 2_500_000 }; 606 scalar(metres) marathon = half_marathon + 607 half_marathon; 608 scalar(litres) two_pools = pool + pool; 609 `marathon + pool;` // compilation ERROR 610 \end{cfa} 611 \end{tabular} 612 \lstMakeShortInline@% 613 \end{cquote} 584 614 @scalar@ is a dtype-static type, so all uses have a single structure definition, containing @unsigned long@, and can share the same implementations of common functions like @?+?@. 585 615 These implementations may even be separately compiled, unlike \CC template functions. … … 1189 1219 `LIF:` if ( ... ) { 1190 1220 `LF:` for ( ... ) { 1191 `LW:` while ( ... ) { 1192 ... break `LC`; ... 1193 ... break `LS`; ... 1194 ... break `LIF`; ... 1195 ... continue `LF;` ... 1196 ... break `LF`; ... 1197 ... continue `LW`; ... 1198 ... break `LW`; ... 1199 } // while 1221 ... break `LC`; ... 1222 ... break `LS`; ... 1223 ... break `LIF`; ... 1224 ... continue `LF;` ... 1225 ... break `LF`; ... 1200 1226 } // for 1201 1227 } else { … … 1213 1239 if ( ... ) { 1214 1240 for ( ... ) { 1215 while ( ... ) { 1216 ... goto `LC`; ... 1217 ... goto `LS`; ... 1218 ... goto `LIF`; ... 1219 ... goto `LFC`; ... 1220 ... goto `LFB`; ... 1221 ... goto `LWC`; ... 1222 ... goto `LWB`; ... 1223 `LWC`: ; } `LWB:` ; 1241 ... goto `LC`; ... 1242 ... goto `LS`; ... 1243 ... goto `LIF`; ... 1244 ... goto `LFC`; ... 1245 ... goto `LFB`; ... 1224 1246 `LFC:` ; } `LFB:` ; 1225 1247 } else { … … 1243 1265 // continue loop 1244 1266 // terminate loop 1245 // continue loop1246 // terminate loop1247 1267 1248 1268 1249 1269 1250 1270 // terminate if 1251 1252 1253 1271 1254 1272 \end{cfa} … … 1411 1429 \label{s:WithStatement} 1412 1430 1413 Grouping heterogeneous data into \newterm{aggregate}s (structure/union) is a common programming practice, and an aggregate can be further organized into more complex structures, such as arrays and containers: 1414 \begin{cfa} 1415 struct S { $\C{// aggregate}$ 1416 char c; $\C{// fields}$ 1417 int i; 1418 double d; 1419 }; 1420 S s, as[10]; 1421 \end{cfa} 1422 However, functions manipulating aggregates must repeat the aggregate name to access its containing fields: 1423 \begin{cfa} 1424 void f( S s ) { 1425 `s.`c; `s.`i; `s.`d; $\C{// access containing fields}$ 1426 } 1427 \end{cfa} 1428 which extends to multiple levels of qualification for nested aggregates. 1429 A similar situation occurs in object-oriented programming, \eg \CC: 1430 \begin{C++} 1431 struct S { 1432 char c; $\C{// fields}$ 1433 int i; 1434 double d; 1435 void f() { $\C{// implicit ``this'' aggregate}$ 1436 `this->`c; `this->`i; `this->`d; $\C{// access containing fields}$ 1437 } 1438 } 1439 \end{C++} 1440 Object-oriented nesting of member functions in a \lstinline[language=C++]@class/struct@ allows eliding \lstinline[language=C++]@this->@ because of lexical scoping. 1441 However, for other aggregate parameters, qualification is necessary: 1442 \begin{cfa} 1431 Heterogeneous data is often aggregated into a structure/union. 1432 To reduce syntactic noise, \CFA provides a @with@ statement (see Pascal~\cite[\S~4.F]{Pascal}) to elide aggregate field-qualification by opening a scope containing the field identifiers. 1433 \begin{cquote} 1434 \vspace*{-\baselineskip}%??? 1435 \lstDeleteShortInline@% 1436 \begin{cfa} 1437 struct S { char c; int i; double d; }; 1443 1438 struct T { double m, n; }; 1444 int S::f( T & t ) { $\C{// multiple aggregate parameters}$ 1445 c; i; d; $\C{\color{red}// this--{\textgreater}.c, this--{\textgreater}.i, this--{\textgreater}.d}$ 1446 `t.`m; `t.`n; $\C{// must qualify}$ 1447 }1448 \end{cfa} 1449 1450 To simplify the programmer experience, \CFA provides a @with@ statement (see Pascal~\cite[\S~4.F]{Pascal}) to elide aggregate qualification to fields by opening a scope containing the field identifiers. 1451 Hence, the qualified fields become variables with the side-effect that it is easier to optimizing field references in a block. 1452 \ begin{cfa}1453 void f( S & this ) `with ( this )` { $\C{// with statement}$ 1454 c; i; d; $\C{\color{red}// this.c, this.i, this.d}$ 1455 } 1456 \end{cfa} 1457 with the generality of opening multiple aggregate-parameters: 1458 \begin{cfa}1459 void f( S & s, T & t ) `with ( s, t )` { $\C{// multiple aggregate parameters}$ 1460 c; i; d; $\C{\color{red}// s.c, s.i, s.d}$ 1461 m; n; $\C{\color{red}// t.m, t.n}$ 1462 }1463 \end{cfa} 1439 // multiple aggregate parameters 1440 \end{cfa} 1441 \begin{tabular}{@{}l@{\hspace{\parindentlnth}}|@{\hspace{\parindentlnth}}l@{}} 1442 \begin{cfa} 1443 void f( S & s, T & t ) { 1444 `s.`c; `s.`i; `s.`d; 1445 `t.`m; `t.`n; 1446 } 1447 \end{cfa} 1448 & 1449 \begin{cfa} 1450 void f( S & s, T & t ) `with ( s, t )` { 1451 c; i; d; // no qualification 1452 m; n; 1453 } 1454 \end{cfa} 1455 \end{tabular} 1456 \lstMakeShortInline@% 1457 \end{cquote} 1458 Object-oriented programming languages only provide implicit qualification for the receiver. 1464 1459 1465 1460 In detail, the @with@ statement has the form: … … 1474 1469 The object is the implicit qualifier for the open structure-fields. 1475 1470 1476 All expressions in the expression list are open in parallel within the compound statement. 1477 This semantic is different from Pascal, which nests the openings from left to right. 1471 All expressions in the expression list are open in parallel within the compound statement, which is different from Pascal, which nests the openings from left to right. 1478 1472 The difference between parallel and nesting occurs for fields with the same name and type: 1479 1473 \begin{cfa} … … 2261 2255 \begin{cfa} 2262 2256 MIN 2257 2263 2258 MAX 2259 2264 2260 PI 2265 2261 E … … 2267 2263 & 2268 2264 \begin{cfa} 2269 SCHAR_MIN, CHAR_MIN, SHRT_MIN, INT_MIN, LONG_MIN, LLONG_MIN, FLT_MIN, DBL_MIN, LDBL_MIN 2270 SCHAR_MAX, UCHAR_MAX, SHRT_MAX, INT_MAX, LONG_MAX, LLONG_MAX, FLT_MAX, DBL_MAX, LDBL_MAX 2265 SCHAR_MIN, CHAR_MIN, SHRT_MIN, INT_MIN, LONG_MIN, 2266 LLONG_MIN, FLT_MIN, DBL_MIN, LDBL_MIN 2267 SCHAR_MAX, UCHAR_MAX, SHRT_MAX, INT_MAX, LONG_MAX, 2268 LLONG_MAX, FLT_MAX, DBL_MAX, LDBL_MAX 2271 2269 M_PI, M_PIl 2272 2270 M_E, M_El … … 2441 2439 ip = (int *)malloc( sizeof( int ) ); memset( ip, fill, dim * sizeof( int ) ); 2442 2440 ip = (int *)realloc( ip, 2 * dim * sizeof( int ) ); 2443 ip = (int *)realloc( ip, 4 * dim * sizeof( int ) ); memset( ip, fill, 4 * dim * sizeof( int ) );2444 2441 ip = (int *)realloc( ip, 4 * dim * sizeof( int ) ); 2442 memset( ip, fill, 4 * dim * sizeof( int ) ); 2445 2443 ip = memalign( 16, sizeof( int ) ); 2446 2444 ip = memalign( 16, sizeof( int ) ); memset( ip, fill, sizeof( int ) ); … … 2607 2605 Though \CFA provides significant added functionality over C, these features have a low runtime penalty. 2608 2606 In fact, \CFA's features for generic programming can enable faster runtime execution than idiomatic @void *@-based C code. 2609 This claim is demonstrated through a set of generic-code-based micro-benchmarks in C, \CFA, and \CC (see stack implementations in Appendix~\ref{sec:BenchmarkStackImplementation }).2607 This claim is demonstrated through a set of generic-code-based micro-benchmarks in C, \CFA, and \CC (see stack implementations in Appendix~\ref{sec:BenchmarkStackImplementations}). 2610 2608 Since all these languages share a subset essentially comprising standard C, maximal-performance benchmarks should show little runtime variance, differing only in length and clarity of source code. 2611 2609 A more illustrative comparison measures the costs of idiomatic usage of each language's features. … … 2824 2822 \appendix 2825 2823 2826 \section{Benchmark Stack Implementation} 2827 \label{sec:BenchmarkStackImplementation} 2828 2829 Throughout, @/***/@ designates a counted redundant type annotation; code reformatted for brevity. 2830 2831 \smallskip\noindent 2832 C 2833 \begin{cfa}[xleftmargin=2\parindentlnth,aboveskip=0pt,belowskip=0pt] 2834 struct stack_node { 2824 \section{Benchmark Stack Implementations} 2825 \label{sec:BenchmarkStackImplementations} 2826 2827 Throughout, @/***/@ designates a counted redundant type annotation; code reformatted slightly for brevity. 2828 2829 2830 \subsection{C} 2831 2832 \begin{flushleft} 2833 \lstDeleteShortInline@% 2834 \begin{tabular}{@{}l@{\hspace{1.8\parindentlnth}}|@{\hspace{\parindentlnth}}l@{}} 2835 \begin{cfa}[xleftmargin=0pt,aboveskip=0pt,belowskip=0pt] 2836 typedef struct node { 2835 2837 void * value; 2836 struct stack_node * next; 2837 }; 2838 struct stack { struct stack_node* head; }; 2839 void clear_stack( struct stack * s, void (*free_el)( void * ) ) { 2840 for ( struct stack_node * next = s->head; next; ) { 2841 struct stack_node * crnt = next; 2842 next = crnt->next; 2843 free_el( crnt->value ); 2844 free( crnt ); 2838 struct node * next; 2839 } node; 2840 typedef struct stack { 2841 struct node * head; 2842 } stack; 2843 void copy_stack( stack * s, const stack * t, 2844 void * (*copy)( const void * ) ) { 2845 node ** cr = &s->head; 2846 for (node * nx = t->head; nx; nx = nx->next) { 2847 *cr = malloc( sizeof(node) ); /***/ 2848 (*cr)->value = copy( nx->value ); 2849 cr = &(*cr)->next; 2850 } 2851 *cr = NULL; 2852 } 2853 void clear_stack( stack * s, void (* free_el)( void * ) ) { 2854 for ( node * nx = s->head; nx; ) { 2855 node * cr = nx; 2856 nx = cr->next; 2857 free_el( cr->value ); 2858 free( cr ); 2845 2859 } 2846 2860 s->head = NULL; 2847 2861 } 2848 struct stack new_stack() { return (struct stack){ NULL }; /***/ } 2849 void copy_stack( struct stack * s, const struct stack * t, void * (*copy)( const void * ) ) { 2850 struct stack_node ** crnt = &s->head; 2851 for ( struct stack_node * next = t->head; next; next = next->next ) { 2852 *crnt = malloc( sizeof(struct stack_node) ); /***/ 2853 (*crnt)->value = copy( next->value ); 2854 crnt = &(*crnt)->next; 2855 } 2856 *crnt = NULL; 2857 } 2858 struct stack * assign_stack( struct stack * s, const struct stack * t, 2859 void * (*copy_el)( const void * ), void (*free_el)( void * ) ) { 2862 \end{cfa} 2863 & 2864 \begin{cfa}[xleftmargin=0pt,aboveskip=0pt,belowskip=0pt] 2865 stack new_stack() { 2866 return (stack){ NULL }; /***/ 2867 } 2868 stack * assign_stack( stack * s, const stack * t, 2869 void * (*copy_el)( const void * ), 2870 void (*free_el)( void * ) ) { 2860 2871 if ( s->head == t->head ) return s; 2861 2872 clear_stack( s, free_el ); /***/ … … 2863 2874 return s; 2864 2875 } 2865 _Bool stack_empty( const struct stack * s ) { return s->head == NULL; } 2866 void push_stack( struct stack * s, void * v ) { 2867 struct stack_node * n = malloc( sizeof(struct stack_node) ); /***/ 2868 *n = (struct stack_node){ v, s->head }; /***/ 2876 _Bool stack_empty( const stack * s ) { 2877 return s->head == NULL; 2878 } 2879 void push_stack( stack * s, void * v ) { 2880 node * n = malloc(sizeof(node)); /***/ 2881 *n = (node){ v, s->head }; /***/ 2869 2882 s->head = n; 2870 2883 } 2871 void * pop_stack( st ruct stack * s ) {2872 struct stack_node * n = s->head;2884 void * pop_stack( stack * s ) { 2885 node * n = s->head; 2873 2886 s->head = n->next; 2874 2887 void * v = n->value; … … 2877 2890 } 2878 2891 \end{cfa} 2879 2880 \medskip\noindent 2881 \CFA 2882 \begin{cfa}[xleftmargin=2\parindentlnth,aboveskip=0pt,belowskip=0pt] 2883 forall( otype T ) struct stack_node { 2884 T value; 2885 stack_node(T) * next; 2886 }; 2887 forall( otype T ) struct stack { stack_node(T) * head; }; 2888 forall( otype T ) void clear( stack(T) & s ) with( s ) { 2889 for ( stack_node(T) * next = head; next; ) { 2890 stack_node(T) * crnt = next; 2891 next = crnt->next; 2892 ^(*crnt){}; 2893 free(crnt); 2892 \end{tabular} 2893 \lstMakeShortInline@% 2894 \end{flushleft} 2895 2896 2897 \subsection{\CFA} 2898 \label{s:CforallStack} 2899 2900 \begin{flushleft} 2901 \lstDeleteShortInline@% 2902 \begin{tabular}{@{}l|@{\hspace{\parindentlnth}}l@{}} 2903 \begin{cfa}[xleftmargin=0pt,aboveskip=0pt,belowskip=0pt] 2904 forall( otype T ) { 2905 struct node { 2906 T value; 2907 node(T) * next; 2908 }; 2909 struct stack { node(T) * head; }; 2910 void ?{}( stack(T) & s ) { (s.head){ 0 }; } 2911 void ?{}( stack(T) & s, stack(T) t ) { 2912 node(T) ** cr = &s.head; 2913 for ( node(T) * nx = t.head; nx; nx = nx->next ) { 2914 *cr = alloc(); 2915 ((*cr)->value){ nx->value }; 2916 cr = &(*cr)->next; 2917 } 2918 *cr = 0; 2894 2919 } 2895 head = 0;2896 }2897 forall( otype T ) void ?{}( stack(T) & s ) { (s.head){ 0 }; }2898 forall( otype T ) void ?{}( stack(T) & s, stack(T) t ) {2899 stack_node(T) ** crnt = &s.head;2900 for ( stack_node(T) * next = t.head; next; next = next->next ) {2901 *crnt = alloc();2902 ((*crnt)->value){ next->value };2903 crnt = &(*crnt)->next;2904 }2905 *crnt = 0;2906 }2907 forall( otype T ) stack(T) ?=?( stack(T) & s, stack(T) t ) {2908 if ( s.head == t.head ) return s;2909 clear( s );2910 s{ t };2911 return s;2912 }2913 forall( otype T ) void ^?{}( stack(T) & s) { clear( s ); }2914 forall( otype T ) _Bool empty( const stack(T) & s ) { return s.head == 0; }2915 forall( otype T ) void push( stack(T) & s, T value ) with( s ) {2916 stack_node(T) * n = alloc();2917 (*n){ value, head };2918 head = n;2919 }2920 forall( otype T ) T pop( stack(T) & s ) with( s ) {2921 stack_node(T) * n = head;2922 head = n->next;2923 T v = n->value;2924 ^(*n){};2925 free( n );2926 return v;2927 }2928 \end{cfa}2929 2930 \begin{comment}2931 forall( otype T ) {2932 struct stack_node {2933 T value;2934 stack_node(T) * next;2935 };2936 struct stack { stack_node(T) * head; };2937 2920 void clear( stack(T) & s ) with( s ) { 2938 for ( stack_node(T) * next = head; next; ) {2939 stack_node(T) * crnt = next;2940 n ext = crnt->next;2941 ^(*cr nt){};2942 free(cr nt);2921 for ( node(T) * nx = head; nx; ) { 2922 node(T) * cr = nx; 2923 nx = cr->next; 2924 ^(*cr){}; 2925 free(cr); 2943 2926 } 2944 2927 head = 0; 2945 2928 } 2946 void ?{}( stack(T) & s ) { (s.head){ 0 }; } 2947 void ?{}( stack(T) & s, stack(T) t ) { 2948 stack_node(T) ** crnt = &s.head; 2949 for ( stack_node(T) * next = t.head; next; next = next->next ) { 2950 *crnt = alloc(); 2951 ((*crnt)->value){ next->value }; 2952 crnt = &(*crnt)->next; 2953 } 2954 *crnt = 0; 2955 } 2929 \end{cfa} 2930 & 2931 \begin{cfa}[xleftmargin=0pt,aboveskip=0pt,belowskip=0pt] 2932 void ^?{}( stack(T) & s) { clear( s ); } 2956 2933 stack(T) ?=?( stack(T) & s, stack(T) t ) { 2957 2934 if ( s.head == t.head ) return s; … … 2960 2937 return s; 2961 2938 } 2962 void ^?{}( stack(T) & s) { clear( s ); } 2963 _Bool empty( const stack(T) & s ) { return s.head == 0; } 2939 _Bool empty( const stack(T) & s ) { 2940 return s.head == 0; 2941 } 2964 2942 void push( stack(T) & s, T value ) with( s ) { 2965 stack_node(T) * n = alloc();2943 node(T) * n = alloc(); 2966 2944 (*n){ value, head }; 2967 2945 head = n; 2968 2946 } 2969 2947 T pop( stack(T) & s ) with( s ) { 2970 stack_node(T) * n = head;2948 node(T) * n = head; 2971 2949 head = n->next; 2972 2950 T v = n->value; … … 2976 2954 } 2977 2955 } 2978 \end{comment} 2979 2980 \medskip\noindent 2981 \CC 2982 \begin{cfa}[xleftmargin=2\parindentlnth,aboveskip=0pt,belowskip=0pt] 2956 2957 \end{cfa} 2958 \end{tabular} 2959 \lstMakeShortInline@% 2960 \end{flushleft} 2961 2962 2963 \subsection{\CC} 2964 2965 \begin{flushleft} 2966 \lstDeleteShortInline@% 2967 \begin{tabular}{@{}l|@{\hspace{\parindentlnth}}l@{}} 2968 \begin{cfa}[xleftmargin=0pt,aboveskip=0pt,belowskip=0pt] 2983 2969 template<typename T> struct stack { 2984 2970 struct node { 2985 2971 T value; 2986 2972 node * next; 2987 node( const T & v, node * n = nullptr ) : value( v ), next( n ) {} 2973 node( const T & v, node * n = nullptr ) : 2974 value( v ), next( n ) {} 2988 2975 }; 2989 2976 node * head; 2990 stack() : head( nullptr ) {} 2991 stack( const stack<T> & o ) { copy( o ); } 2977 void copy( const stack<T> & o ) { 2978 node ** cr = &head; 2979 for ( node * nx = o.head; nx; nx = nx->next ) { 2980 *cr = new node{ nx->value }; /***/ 2981 cr = &(*cr)->next; 2982 } 2983 *cr = nullptr; 2984 } 2992 2985 void clear() { 2993 for ( node * n ext = head; next; ) {2994 node * cr nt = next;2995 n ext = crnt->next;2996 delete cr nt;2986 for ( node * nx = head; nx; ) { 2987 node * cr = nx; 2988 nx = cr->next; 2989 delete cr; 2997 2990 } 2998 2991 head = nullptr; 2999 2992 } 3000 void copy( const stack<T> & o ) { 3001 node ** crnt = &head; 3002 for ( node * next = o.head; next; next = next->next ) { 3003 *crnt = new node{ next->value }; /***/ 3004 crnt = &(*crnt)->next; 3005 } 3006 *crnt = nullptr; 3007 } 2993 \end{cfa} 2994 & 2995 \begin{cfa}[xleftmargin=0pt,aboveskip=0pt,belowskip=0pt] 2996 stack() : head( nullptr ) {} 2997 stack( const stack<T> & o ) { copy( o ); } 3008 2998 ~stack() { clear(); } 3009 stack & operator= 2999 stack & operator=( const stack<T> & o ) { 3010 3000 if ( this == &o ) return *this; 3011 3001 clear(); … … 3014 3004 } 3015 3005 bool empty() const { return head == nullptr; } 3016 void push( const T & value ) { head = new node{ value, head }; /***/ } 3006 void push( const T & value ) { 3007 head = new node{ value, head }; /***/ 3008 } 3017 3009 T pop() { 3018 3010 node * n = head; … … 3023 3015 } 3024 3016 }; 3025 \end{cfa} 3026 3027 \medskip\noindent 3028 \CCV 3029 \begin{cfa}[xleftmargin=2\parindentlnth,aboveskip=0pt,belowskip=0pt] 3017 3018 3019 3020 \end{cfa} 3021 \end{tabular} 3022 \lstMakeShortInline@% 3023 \end{flushleft} 3024 3025 3026 \subsection{\CCV} 3027 3028 \begin{flushleft} 3029 \lstDeleteShortInline@% 3030 \begin{tabular}{@{}l|@{\hspace{\parindentlnth}}l@{}} 3031 \begin{cfa}[xleftmargin=0pt,aboveskip=0pt,belowskip=0pt] 3030 3032 struct stack { 3031 3033 struct node { 3032 3034 ptr<object> value; 3033 3035 node * next; 3034 node( const object & v, node * n = nullptr ) : value( v.new_copy() ), next( n ) {} 3036 node( const object & v, node * n = nullptr ) : 3037 value( v.new_copy() ), next( n ) {} 3035 3038 }; 3036 3039 node * head; 3040 void copy( const stack & o ) { 3041 node ** cr = &head; 3042 for ( node * nx = o.head; nx; nx = nx->next ) { 3043 *cr = new node{ *nx->value }; /***/ 3044 cr = &(*cr)->next; 3045 } 3046 *cr = nullptr; 3047 } 3037 3048 void clear() { 3038 for ( node * n ext = head; next; ) {3039 node * cr nt = next;3040 n ext = crnt->next;3041 delete cr nt;3049 for ( node * nx = head; nx; ) { 3050 node * cr = nx; 3051 nx = cr->next; 3052 delete cr; 3042 3053 } 3043 3054 head = nullptr; 3044 3055 } 3045 void copy( const stack & o ) { 3046 node ** crnt = &head; 3047 for ( node * next = o.head; next; next = next->next ) { 3048 *crnt = new node{ *next->value }; /***/ 3049 crnt = &(*crnt)->next; 3050 } 3051 *crnt = nullptr; 3052 } 3056 \end{cfa} 3057 & 3058 \begin{cfa}[xleftmargin=0pt,aboveskip=0pt,belowskip=0pt] 3053 3059 stack() : head( nullptr ) {} 3054 3060 stack( const stack & o ) { copy( o ); } 3055 3061 ~stack() { clear(); } 3056 stack & operator= 3062 stack & operator=( const stack & o ) { 3057 3063 if ( this == &o ) return *this; 3058 3064 clear(); … … 3061 3067 } 3062 3068 bool empty() const { return head == nullptr; } 3063 void push( const object & value ) { head = new node{ value, head }; /***/ } 3069 void push( const object & value ) { 3070 head = new node{ value, head }; /***/ 3071 } 3064 3072 ptr<object> pop() { 3065 3073 node * n = head; … … 3070 3078 } 3071 3079 }; 3072 \end{cfa} 3080 3081 3082 3083 \end{cfa} 3084 \end{tabular} 3085 \lstMakeShortInline@% 3086 \end{flushleft} 3073 3087 3074 3088 -
doc/papers/general/evaluation/c-bench.c
ra0c7d5cc r534d84e 5 5 #include "c-stack.h" 6 6 7 char * new_char( char c ) {8 char* q = malloc( sizeof(char)); /***/7 char * new_char( char c ) { 8 char* q = malloc( sizeof(char) ); /***/ 9 9 *q = c; 10 10 return q; 11 11 } 12 12 13 short * new_short( short s ) {14 short* q = malloc( sizeof(short)); /***/13 short * new_short( short s ) { 14 short* q = malloc( sizeof(short) ); /***/ 15 15 *q = s; 16 16 return q; … … 18 18 19 19 int* new_int( int i ) { 20 int* q = malloc( sizeof(int)); /***/20 int* q = malloc( sizeof(int) ); /***/ 21 21 *q = i; 22 22 return q; 23 23 } 24 24 25 void * copy_char( const void* p ) { return new_char( *(const char*)p ); } /***/26 void * copy_short( const void* p ) { return new_short( *(const short*)p ); } /***/27 void * copy_int( const void* p ) { return new_int( *(const int*)p ); } /***/28 void * copy_pair_short_char( const void* p ) { return copy_pair( p, copy_short, copy_char ); } /***/29 void free_pair_short_char( void * p ) { free_pair( p, free, free ); } /***/25 void * copy_char( const void * p ) { return new_char( *(const char*)p ); } /***/ 26 void * copy_short( const void * p ) { return new_short( *(const short*)p ); } /***/ 27 void * copy_int( const void * p ) { return new_int( *(const int*)p ); } /***/ 28 void * copy_pair_short_char( const void * p ) { return copy_pair( p, copy_short, copy_char ); } /***/ 29 void free_pair_short_char( void * p ) { free_pair( p, free, free ); } /***/ 30 30 31 31 int cmp_char( const void* a, const void* b ) { /***/ … … 37 37 } 38 38 39 int main(int argc, char ** argv) {39 int main(int argc, char * argv[] ) { 40 40 int maxi = 0, vali = 42; 41 41 struct stack si = new_stack(), ti; -
doc/papers/general/evaluation/c-pair.c
ra0c7d5cc r534d84e 2 2 #include "c-pair.h" 3 3 4 struct pair* new_pair(void* first, void* second) {5 struct pair* p = malloc(sizeof(struct pair)); /***/6 *p = ( structpair){ first, second }; /***/4 pair * new_pair( void * first, void * second ) { 5 pair * p = malloc( sizeof(pair) ); /***/ 6 *p = (pair){ first, second }; /***/ 7 7 return p; 8 8 } 9 9 10 struct pair* copy_pair(const struct pair* src,11 void * (*copy_first)(const void*), void* (*copy_second)(const void*)) {10 pair * copy_pair( const pair * src, 11 void * (* copy_first)(const void* ), void * (* copy_second)(const void *)) { 12 12 return new_pair( copy_first(src->first), copy_second(src->second) ); 13 13 } 14 14 15 void free_pair( struct pair* p, void (*free_first)(void*), void (*free_second)(void*)) {16 free_first( p->first);17 free_second( p->second);18 free( p);15 void free_pair( pair * p, void (* free_first)(void *), void (* free_second)(void *)) { 16 free_first( p->first ); 17 free_second( p->second ); 18 free( p ); 19 19 } 20 20 21 int cmp_pair( const struct pair* a, const struct pair* b,22 int (* cmp_first)(const void*, const void*), int (*cmp_second)(const void*, const void*)) {23 int c = cmp_first( a->first, b->first);24 if ( c == 0 ) c = cmp_second( a->second, b->second);21 int cmp_pair( const pair * a, const pair * b, 22 int (* cmp_first)(const void *, const void *), int (* cmp_second)(const void *, const void *)) { 23 int c = cmp_first( a->first, b->first ); 24 if ( c == 0 ) c = cmp_second( a->second, b->second ); 25 25 return c; 26 26 } -
doc/papers/general/evaluation/c-pair.h
ra0c7d5cc r534d84e 1 1 #pragma once 2 2 3 struct pair {4 void * first;5 void * second;6 } ;3 typedef struct pair { 4 void * first; 5 void * second; 6 } pair; 7 7 8 struct pair* new_pair(void* first, void* second);8 pair * new_pair( void * first, void * second ); 9 9 10 struct pair* copy_pair(const struct pair* src,11 void * (*copy_first)(const void*), void* (*copy_second)(const void*));10 pair * copy_pair( const pair * src, 11 void * (* copy_first)(const void *), void * (* copy_second)(const void *)); 12 12 13 void free_pair( struct pair* p, void (*free_first)(void*), void (*free_second)(void*));13 void free_pair( pair * p, void (* free_first)(void *), void (* free_second)(void *)); 14 14 15 int cmp_pair( const struct pair* a, const struct pair* b,16 int (* cmp_first)(const void*, const void*), int (*cmp_second)(const void*, const void*));15 int cmp_pair( const pair * a, const pair * b, 16 int (* cmp_first)(const void *, const void *), int (* cmp_second)(const void *, const void *)); -
doc/papers/general/evaluation/c-print.c
ra0c7d5cc r534d84e 4 4 #include "c-print.h" 5 5 6 void print_string( FILE* out, const char* x) { fprintf(out, "%s", x); }6 void print_string( FILE * out, const char * x ) { fprintf( out, "%s", x ); } 7 7 8 void print_bool( FILE* out, _Bool x) { fprintf(out, "%s", x ? "true" : "false"); }8 void print_bool( FILE * out, _Bool x ) { fprintf( out, "%s", x ? "true" : "false" ); } 9 9 10 void print_char( FILE* out, char x) {11 if ( 0x20 <= x && x <= 0x7E ) { fprintf( out, "'%c'", x); }12 else { fprintf( out, "'\\%x'", x); }10 void print_char( FILE * out, char x ) { 11 if ( 0x20 <= x && x <= 0x7E ) { fprintf( out, "'%c'", x ); } 12 else { fprintf( out, "'\\%x'", x ); } 13 13 } 14 14 15 void print_int( FILE* out, int x) { fprintf(out, "%d", x); }15 void print_int( FILE * out, int x ) { fprintf( out, "%d", x ); } 16 16 17 void print_fmt( FILE* out, char fmt, void* p) {17 void print_fmt( FILE * out, char fmt, void * p ) { 18 18 switch( fmt ) { 19 case 's': print_string( out, (const char*)p); break; /***/20 case 'b': print_bool( out, *(_Bool*)p); break; /***/21 case 'c': print_char( out, *(char*)p); break; /***/22 case 'd': print_int( out, *(int*)p); break; /***/19 case 's': print_string( out, (const char*)p ); break; /***/ 20 case 'b': print_bool( out, *(_Bool*)p ); break; /***/ 21 case 'c': print_char( out, *(char*)p ); break; /***/ 22 case 'd': print_int( out, *(int*)p ); break; /***/ 23 23 } 24 24 } 25 25 26 void print( FILE* out, const char* fmt, ...) {26 void print( FILE * out, const char * fmt, ... ) { 27 27 va_list args; 28 28 va_start(args, fmt); 29 for ( const char* it = fmt; *it; ++it) {29 for ( const char * it = fmt; *it; ++it ) { 30 30 switch( *it ) { 31 case 's': print_string( out, va_arg(args, const char*)); break; /***/32 case 'b': print_bool( out, va_arg(args, int)); break; /***/33 case 'c': print_char( out, va_arg(args, int)); break; /***/34 case 'd': print_int( out, va_arg(args, int)); break; /***/31 case 's': print_string( out, va_arg( args, const char * ) ); break; /***/ 32 case 'b': print_bool( out, va_arg( args, int ) ); break; /***/ 33 case 'c': print_char( out, va_arg( args, int ) ); break; /***/ 34 case 'd': print_int( out, va_arg( args, int ) ); break; /***/ 35 35 case 'p': { 36 const struct pair x = va_arg( args, const struct pair); /***/37 fprintf( out, "[");38 print_fmt( out, *++it, x.first); /***/39 fprintf( out, ", ");40 print_fmt( out, *++it, x.second); /***/41 fprintf( out, "]");36 const struct pair x = va_arg( args, const struct pair ); /***/ 37 fprintf( out, "[" ); 38 print_fmt( out, *++it, x.first ); /***/ 39 fprintf( out, ", " ); 40 print_fmt( out, *++it, x.second ); /***/ 41 fprintf( out, "]" ); 42 42 break; 43 43 } 44 44 } 45 45 } 46 va_end( args);46 va_end( args ); 47 47 } -
doc/papers/general/evaluation/c-print.h
ra0c7d5cc r534d84e 2 2 #include <stdio.h> 3 3 4 void print_string( FILE* out, const char* x);5 void print_bool( FILE* out, _Bool x);6 void print_char( FILE* out, char x);7 void print_int( FILE* out, int x);4 void print_string( FILE * out, const char * x ); 5 void print_bool( FILE * out, _Bool x ); 6 void print_char( FILE * out, char x ); 7 void print_int( FILE * out, int x ); 8 8 9 void print( FILE* out, const char* fmt, ...);9 void print( FILE * out, const char * fmt, ... ); -
doc/papers/general/evaluation/c-stack.c
ra0c7d5cc r534d84e 2 2 #include "c-stack.h" 3 3 4 struct stack_node {4 typedef struct node { 5 5 void * value; 6 struct stack_node * next;7 } ;6 struct node * next; 7 } node; 8 8 9 void clear_stack( struct stack * s, void (*free_el)( void * ) ) { 10 for ( struct stack_node * next = s->head; next; ) { 11 struct stack_node * crnt = next; 12 next = crnt->next; 13 free_el( crnt->value ); 14 free( crnt ); 9 void copy_stack( stack * s, const stack * t, void * (*copy)( const void * ) ) { 10 node ** cr = &s->head; 11 for ( node * nx = t->head; nx; nx = nx->next ) { 12 *cr = malloc( sizeof(node) ); /***/ 13 (*cr)->value = copy( nx->value ); 14 cr = &(*cr)->next; 15 } 16 *cr = NULL; 17 } 18 19 void clear_stack( stack * s, void (* free_el)( void * ) ) { 20 for ( node * nx = s->head; nx; ) { 21 node * cr = nx; 22 nx = cr->next; 23 free_el( cr->value ); 24 free( cr ); 15 25 } 16 26 s->head = NULL; 17 27 } 18 28 19 st ruct stack new_stack() { return (structstack){ NULL }; /***/ }29 stack new_stack() { return (stack){ NULL }; /***/ } 20 30 21 void copy_stack( struct stack * s, const struct stack * t, void * (*copy)( const void * ) ) { 22 struct stack_node ** crnt = &s->head; 23 for ( struct stack_node * next = t->head; next; next = next->next ) { 24 *crnt = malloc( sizeof(struct stack_node) ); /***/ 25 (*crnt)->value = copy( next->value ); 26 crnt = &(*crnt)->next; 27 } 28 *crnt = NULL; 29 } 30 struct stack * assign_stack( struct stack * s, const struct stack * t, 31 stack * assign_stack( stack * s, const stack * t, 31 32 void * (*copy_el)( const void * ), void (*free_el)( void * ) ) { 32 33 if ( s->head == t->head ) return s; … … 36 37 } 37 38 38 _Bool stack_empty( const st ruct stack * s ) { return s->head == NULL; }39 _Bool stack_empty( const stack * s ) { return s->head == NULL; } 39 40 40 void push_stack( st ruct stack * s, void * v ) {41 struct stack_node * n = malloc( sizeof(struct stack_node) ); /***/42 *n = ( struct stack_node){ v, s->head }; /***/41 void push_stack( stack * s, void * v ) { 42 node * n = malloc( sizeof(node) ); /***/ 43 *n = (node){ v, s->head }; /***/ 43 44 s->head = n; 44 45 } 45 46 46 void * pop_stack( st ruct stack * s ) {47 struct stack_node * n = s->head;47 void * pop_stack( stack * s ) { 48 node * n = s->head; 48 49 s->head = n->next; 49 50 void * v = n->value; -
doc/papers/general/evaluation/c-stack.h
ra0c7d5cc r534d84e 1 1 #pragma once 2 2 3 struct stack_node;4 struct stack {5 struct stack_node* head;6 } ;3 struct node; 4 typedef struct stack { 5 struct node * head; 6 } stack; 7 7 8 st ruct stack new_stack();9 void copy_stack(st ruct stack* dst, const struct stack* src, void* (*copy)(const void*));10 st ruct stack* assign_stack(struct stack* dst, const struct stack* src,11 void * (*copy_el)(const void*), void (*free_el)(void*));12 void clear_stack(st ruct stack* s, void (*free_el)(void*));8 stack new_stack(); 9 void copy_stack(stack * dst, const stack * src, void * (* copy)(const void *)); 10 stack * assign_stack( stack * dst, const stack * src, 11 void * (* copy_el)(const void *), void (* free_el)(void *)); 12 void clear_stack(stack * s, void (*free_el)(void *)); 13 13 14 _Bool stack_empty( const struct stack* s);15 void push_stack( struct stack* s, void* value);16 void * pop_stack(struct stack* s);14 _Bool stack_empty( const stack * s ); 15 void push_stack( stack * s, void * value ); 16 void * pop_stack( stack * s ); -
doc/papers/general/evaluation/cfa-stack.c
ra0c7d5cc r534d84e 2 2 #include "cfa-stack.h" 3 3 4 forall( otype T ) struct stack_node { 5 T value; 6 stack_node(T) * next; 7 }; 4 forall( otype T ) { 5 struct node { 6 T value; 7 node(T) * next; 8 }; 8 9 9 forall( otype T ) void clear( stack(T) & s ) with( s ) { 10 for ( stack_node(T) * next = head; next; ) { 11 stack_node(T) * crnt = next; 12 next = crnt->next; 13 ^(*crnt){}; 14 free(crnt); 10 void ?{}( stack(T) & s ) { (s.head){ 0 }; } 11 12 void ?{}( stack(T) & s, stack(T) t ) { 13 node(T) ** cr = &s.head; 14 for ( node(T) * nx = t.head; nx; nx = nx->next ) { 15 *cr = alloc(); 16 ((*cr)->value){ nx->value }; 17 cr = &(*cr)->next; 18 } 19 *cr = 0; 15 20 } 16 head = 0; 21 22 void ^?{}( stack(T) & s) { clear( s ); } 23 24 void clear( stack(T) & s ) with( s ) { 25 for ( node(T) * nx = head; nx; ) { 26 node(T) * cr = nx; 27 nx = cr->next; 28 ^(*cr){}; 29 free(cr); 30 } 31 head = 0; 32 } 33 34 stack(T) ?=?( stack(T) & s, stack(T) t ) { 35 if ( s.head == t.head ) return s; 36 clear( s ); 37 s{ t }; 38 return s; 39 } 40 41 _Bool empty( const stack(T) & s ) { return s.head == 0; } 42 43 void push( stack(T) & s, T value ) with( s ) { 44 node(T) * n = alloc(); 45 (*n){ value, head }; 46 head = n; 47 } 48 49 T pop( stack(T) & s ) with( s ) { 50 node(T) * n = head; 51 head = n->next; 52 T v = n->value; 53 ^(*n){}; 54 free( n ); 55 return v; 56 } 17 57 } 18 19 forall( otype T ) void ?{}( stack(T) & s ) { (s.head){ 0 }; }20 21 forall( otype T ) void ?{}( stack(T) & s, stack(T) t ) {22 stack_node(T) ** crnt = &s.head;23 for ( stack_node(T) * next = t.head; next; next = next->next ) {24 *crnt = alloc();25 ((*crnt)->value){ next->value };26 crnt = &(*crnt)->next;27 }28 *crnt = 0;29 }30 31 forall( otype T ) stack(T) ?=?( stack(T) & s, stack(T) t ) {32 if ( s.head == t.head ) return s;33 clear( s );34 s{ t };35 return s;36 }37 38 forall( otype T ) void ^?{}( stack(T) & s) { clear( s ); }39 40 forall( otype T ) _Bool empty( const stack(T) & s ) { return s.head == 0; }41 42 forall( otype T ) void push( stack(T) & s, T value ) with( s ) {43 stack_node(T) * n = alloc();44 (*n){ value, head };45 head = n;46 }47 48 forall( otype T ) T pop( stack(T) & s ) with( s ) {49 stack_node(T) * n = head;50 head = n->next;51 T v = n->value;52 ^(*n){};53 free( n );54 return v;55 } -
doc/papers/general/evaluation/cfa-stack.h
ra0c7d5cc r534d84e 1 1 #pragma once 2 2 3 forall( otype T ) struct stack_node; 4 forall( otype T ) struct stack { 5 stack_node(T) * head; 6 }; 3 forall( otype T ) { 4 struct node; 5 struct stack { 6 node(T) * head; 7 }; 7 8 8 forall( otype T )void ?{}( stack(T) & s );9 forall( otype T )void ?{}( stack(T) & s, stack(T) t );10 forall( otype T ) stack(T) ?=?( stack(T) & s, stack(T) t);11 forall( otype T ) void ^?{}( stack(T) & s);9 void ?{}( stack(T) & s ); 10 void ?{}( stack(T) & s, stack(T) t ); 11 void ^?{}( stack(T) & s); 12 void clear( stack(T) & s ); 12 13 13 forall( otype T ) _Bool empty( const stack(T) & s ); 14 forall( otype T ) void push( stack(T) & s, T value ); 15 forall( otype T ) T pop( stack(T) & s ); 16 forall( otype T ) void clear( stack(T) & s ); 14 stack(T) ?=?( stack(T) & s, stack(T) t ); 15 _Bool empty( const stack(T) & s ); 16 void push( stack(T) & s, T value ); 17 T pop( stack(T) & s ); 18 } -
doc/papers/general/evaluation/cpp-stack.hpp
ra0c7d5cc r534d84e 14 14 15 15 void clear() { 16 for ( node * n ext = head; next; ) {17 node * cr nt = next;18 n ext = crnt->next;19 delete cr nt;16 for ( node * nx = head; nx; ) { 17 node * cr = nx; 18 nx = cr->next; 19 delete cr; 20 20 } 21 21 head = nullptr; … … 23 23 24 24 void copy( const stack<T> & o ) { 25 node ** cr nt= &head;26 for ( node * n ext = o.head; next; next = next->next ) {27 *cr nt = new node{ next->value }; /***/28 cr nt = &(*crnt)->next;25 node ** cr = &head; 26 for ( node * nx = o.head; nx; nx = nx->next ) { 27 *cr = new node{ nx->value }; /***/ 28 cr = &(*cr)->next; 29 29 } 30 *cr nt= nullptr;30 *cr = nullptr; 31 31 } 32 32 -
doc/papers/general/evaluation/cpp-vstack.cpp
ra0c7d5cc r534d84e 5 5 6 6 void stack::clear() { 7 for ( node * n ext = head; next; ) {8 node * cr nt = next;9 n ext = crnt->next;10 delete cr nt;7 for ( node * nx = head; nx; ) { 8 node * cr = nx; 9 nx = cr->next; 10 delete cr; 11 11 } 12 12 head = nullptr; … … 14 14 15 15 void stack::copy( const stack & o ) { 16 node ** cr nt= &head;17 for ( node * n ext = o.head; next; next = next->next ) {18 *cr nt = new node{ *next->value }; /***/19 cr nt = &(*crnt)->next;16 node ** cr = &head; 17 for ( node * nx = o.head; nx; nx = nx->next ) { 18 *cr = new node{ *nx->value }; /***/ 19 cr = &(*cr)->next; 20 20 } 21 *cr nt= nullptr;21 *cr = nullptr; 22 22 } 23 23 -
src/Parser/DeclarationNode.cc
ra0c7d5cc r534d84e 10 10 // Created On : Sat May 16 12:34:05 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Fri Apr 20 22:37:20 201813 // Update Count : 106 312 // Last Modified On : Thu Apr 26 13:45:10 2018 13 // Update Count : 1064 14 14 // 15 15 … … 783 783 DeclarationNode * DeclarationNode::addPointer( DeclarationNode * p ) { 784 784 if ( p ) { 785 assert( p->type->kind == TypeData::Pointer || TypeData::Reference );785 assert( p->type->kind == TypeData::Pointer || p->type->kind == TypeData::Reference ); 786 786 setBase( p->type ); 787 787 p->type = nullptr; -
src/Parser/TypeData.cc
ra0c7d5cc r534d84e 10 10 // Created On : Sat May 16 15:12:51 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : T ue Apr 17 23:00:52201813 // Update Count : 60 212 // Last Modified On : Thu Apr 26 13:46:07 2018 13 // Update Count : 603 14 14 // 15 15 … … 62 62 enumeration.constants = nullptr; 63 63 enumeration.body = false; 64 break; 64 65 case Aggregate: 65 66 // aggregate = new Aggregate_t; -
src/Parser/parser.yy
ra0c7d5cc r534d84e 10 10 // Created On : Sat Sep 1 20:22:55 2001 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Tue Apr 17 17:10:30201813 // Update Count : 3 14412 // Last Modified On : Sat Apr 28 09:37:03 2018 13 // Update Count : 3201 14 14 // 15 15 … … 133 133 } // build_postfix_name 134 134 135 bool forall = false ;// aggregate have one or more forall qualifiers ?135 bool forall = false, xxx = false; // aggregate have one or more forall qualifiers ? 136 136 137 137 // https://www.gnu.org/software/bison/manual/bison.html#Location-Type … … 282 282 %type<decl> aggregate_type aggregate_type_nobody 283 283 284 %type<decl> assertion assertion_list _opt284 %type<decl> assertion assertion_list assertion_list_opt 285 285 286 286 %type<en> bit_subrange_size_opt bit_subrange_size … … 1866 1866 { 1867 1867 typedefTable.makeTypedef( *$3 ); 1868 if ( forall ) typedefTable.changeKind( *$3, TypedefTable::TG ); // possibly update 1869 forall = false; // reset 1868 1870 $$ = DeclarationNode::newAggregate( $1, $3, nullptr, nullptr, false )->addQualifiers( $2 ); 1869 1871 } … … 2235 2237 { $$ = DeclarationNode::newTypeParam( $1, $2 )->addTypeInitializer( $4 )->addAssertions( $5 ); } 2236 2238 | type_specifier identifier_parameter_declarator 2239 | assertion_list 2240 { $$ = DeclarationNode::newTypeParam( DeclarationNode::Dtype, new string( DeclarationNode::anonymous.newName() ) )->addAssertions( $1 ); } 2237 2241 ; 2238 2242 … … 2251 2255 // empty 2252 2256 { $$ = nullptr; } 2253 | assertion_list_opt assertion 2257 | assertion_list 2258 ; 2259 2260 assertion_list: // CFA 2261 assertion 2262 | assertion_list assertion 2254 2263 { $$ = $1 ? $1->appendList( $2 ) : $2; } 2255 2264 ; … … 2378 2387 external_definition_list: 2379 2388 external_definition 2380 | external_definition_list push external_definition2381 { $$ = $1 ? $1->appendList( $ 3 ) : $3; }2389 | external_definition_list { forall = xxx; } push external_definition 2390 { $$ = $1 ? $1->appendList( $4 ) : $4; } 2382 2391 ; 2383 2392 … … 2411 2420 $$ = $2; 2412 2421 } 2413 | type_qualifier_list '{' external_definition_list '}' // CFA, namespace 2422 | type_qualifier_list 2423 { 2424 if ( $1->type->forall ) xxx = forall = true; // remember generic type 2425 } 2426 push '{' external_definition_list '}' // CFA, namespace 2427 { 2428 for ( DeclarationNode * iter = $5; iter != nullptr; iter = (DeclarationNode *)iter->get_next() ) { 2429 iter->addQualifiers( $1->clone() ); 2430 } // for 2431 xxx = false; 2432 delete $1; 2433 $$ = $5; 2434 } 2435 | declaration_qualifier_list 2436 { 2437 if ( $1->type->forall ) xxx = forall = true; // remember generic type 2438 } 2439 push '{' external_definition_list '}' // CFA, namespace 2440 { 2441 for ( DeclarationNode * iter = $5; iter != nullptr; iter = (DeclarationNode *)iter->get_next() ) { 2442 iter->addQualifiers( $1->clone() ); 2443 } // for 2444 xxx = false; 2445 delete $1; 2446 $$ = $5; 2447 } 2448 | declaration_qualifier_list type_qualifier_list 2449 { 2450 if ( $1->type->forall ) xxx = forall = true; // remember generic type 2451 } 2452 push '{' external_definition_list '}' // CFA, namespace 2453 { 2454 for ( DeclarationNode * iter = $6; iter != nullptr; iter = (DeclarationNode *)iter->get_next() ) { 2455 iter->addQualifiers( $1->clone() ); 2456 iter->addQualifiers( $2->clone() ); 2457 } // for 2458 xxx = false; 2459 delete $1; 2460 delete $2; 2461 $$ = $6; 2462 } 2414 2463 ; 2415 2464 … … 2437 2486 with_clause_opt: 2438 2487 // empty 2439 { $$ = nullptr; }2488 { $$ = nullptr; forall = false; } 2440 2489 | WITH '(' tuple_expression_list ')' 2441 { $$ = $3; }2490 { $$ = $3; forall = false; } 2442 2491 ; 2443 2492 -
src/SymTab/Autogen.cc
ra0c7d5cc r534d84e 9 9 // Author : Rob Schluntz 10 10 // Created On : Thu Mar 03 15:45:56 2016 11 // Last Modified By : Andrew Beach12 // Last Modified On : Fri Jul 14 16:41:00 201713 // Update Count : 6 211 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Fri Apr 27 14:39:06 2018 13 // Update Count : 63 14 14 // 15 15 … … 331 331 definitions.push_back( dcl ); 332 332 indexer.addId( dcl ); 333 } catch ( SemanticErrorException err) {333 } catch ( SemanticErrorException & ) { 334 334 // okay if decl does not resolve - that means the function should not be generated 335 335 delete dcl;
Note: See TracChangeset
for help on using the changeset viewer.