- Timestamp:
- Mar 8, 2018, 11:04:14 PM (7 years ago)
- Branches:
- ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, deferred_resn, demangler, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, with_gc
- Children:
- 81e8ab0, e59f0bf
- Parents:
- deb52a0
- Location:
- doc
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
doc/bibliography/pl.bib
rdeb52a0 r29db723 6061 6061 } 6062 6062 6063 @article{Nickolls08, 6064 author = {Nickolls, John and Buck, Ian and Garland, Michael and Skadron, Kevin}, 6065 title = {Scalable Parallel Programming with CUDA}, 6066 journal = {Queue}, 6067 volume = {6}, 6068 number = {2}, 6069 month = mar, 6070 year = 2008, 6071 pages = {40-53}, 6072 publisher = {ACM}, 6073 address = {New York, NY, USA}, 6074 } 6075 6063 6076 @inproceedings{Leissa14, 6064 title={Sierra: a SIMD extension for C++},6065 author={Lei{\ss}a, Roland and Haffner, Immanuel and Hack, Sebastian},6066 booktitle={Proceedings of the 2014 Workshop on Workshop on programming models for SIMD/Vector processing},6067 pages={17--24},6068 year={2014},6069 organization={ACM}6077 title = {Sierra: a SIMD extension for C++}, 6078 author = {Lei{\ss}a, Roland and Haffner, Immanuel and Hack, Sebastian}, 6079 booktitle = {Proceedings of the 2014 Workshop on Workshop on programming models for SIMD/Vector processing}, 6080 pages = {17--24}, 6081 year = {2014}, 6082 organization= {ACM} 6070 6083 } 6071 6084 … … 6310 6323 @article{Smith98, 6311 6324 keywords = {Polymorphic C}, 6312 contributor 6325 contributor = {a3moss@uwaterloo.ca}, 6313 6326 title = {A sound polymorphic type system for a dialect of C}, 6314 6327 author = {Smith, Geoffrey and Volpano, Dennis}, -
doc/papers/general/Paper.tex
rdeb52a0 r29db723 146 146 % replace/adjust listing characters that look bad in sanserif 147 147 literate={-}{\makebox[1ex][c]{\raisebox{0.4ex}{\rule{0.8ex}{0.1ex}}}}1 {^}{\raisebox{0.6ex}{$\scriptscriptstyle\land\,$}}1 148 {~}{\raisebox{0.3ex}{$\scriptstyle\sim\,$}}1 {@}{\small{@}}1 % {`}{\ttfamily\upshape\hspace*{-0.1ex}`}1149 {<-}{$\leftarrow$}2 {=>}{$\Rightarrow$}2 {->}{\makebox[1ex][c]{\raisebox{0.4ex}{\rule{0.8ex}{0.075ex}}}\kern-0.2ex \textgreater}2,148 {~}{\raisebox{0.3ex}{$\scriptstyle\sim\,$}}1 {@}{\small{@}}1 {<}{\small{\textless}}1 {>}{\small{\textgreater}}1 % {`}{\ttfamily\upshape\hspace*{-0.1ex}`}1 149 {<-}{$\leftarrow$}2 {=>}{$\Rightarrow$}2 {->}{\makebox[1ex][c]{\raisebox{0.4ex}{\rule{0.8ex}{0.075ex}}}\kern-0.2ex{\small\textgreater}}2, 150 150 moredelim=**[is][\color{red}]{`}{`}, 151 151 }% lstset … … 436 436 One approach is to write bespoke data-structures for each context in which they are needed. 437 437 While this approach is flexible and supports integration with the C type-checker and tooling, it is also tedious and error-prone, especially for more complex data structures. 438 A second approach is to use @void *@ 438 A second approach is to use @void *@-based polymorphism, \eg the C standard-library functions @bsearch@ and @qsort@, which allow reuse of code with common functionality. 439 439 However, basing all polymorphism on @void *@ eliminates the type-checker's ability to ensure that argument types are properly matched, often requiring a number of extra function parameters, pointer indirection, and dynamic allocation that is not otherwise needed. 440 440 A third approach to generic code is to use preprocessor macros, which does allow the generated code to be both generic and type-checked, but errors may be difficult to interpret. … … 526 526 Results of these layout functions are cached so that they are only computed once per type per function. %, as in the example below for @pair@. 527 527 Layout functions also allow generic types to be used in a function definition without reflecting them in the function signature. 528 For instance, a function that strips duplicate values from an unsorted @vector(T)@ would likely have a pointer to the vector as its only explicit parameter, but usesome sort of @set(T)@ internally to test for duplicate values.528 For instance, a function that strips duplicate values from an unsorted @vector(T)@ likely has a pointer to the vector as its only explicit parameter, but uses some sort of @set(T)@ internally to test for duplicate values. 529 529 This function could acquire the layout for @set(T)@ by calling its layout function with the layout of @T@ implicitly passed into the function. 530 530 … … 796 796 Since @void@ is effectively a 0-element tuple, (3) discards the first and third return values, which is effectively equivalent to @[(int)(g().1.0), (int)(g().1.1)]@). 797 797 798 Note that a cast is not a function call in \CFA, so flattening and structuring conversions do not occur for cast expressions\footnote{User-defined conversions have been considered, but for compatibility with C and the existing use of casts as type ascription, any future design for such conversions would requiremore precise matching of types than allowed for function arguments and parameters.}.798 Note that a cast is not a function call in \CFA, so flattening and structuring conversions do not occur for cast expressions\footnote{User-defined conversions have been considered, but for compatibility with C and the existing use of casts as type ascription, any future design for such conversions requires more precise matching of types than allowed for function arguments and parameters.}. 799 799 As such, (4) is invalid because the cast target type contains 4 components, while the source type contains only 3. 800 800 Similarly, (5) is invalid because the cast @([int, int, int])(g().1)@ is invalid. … … 1159 1159 case 4: 1160 1160 ... `fallthrough common;` 1161 common: 1161 common: // below fallthrough and at same level as case clauses 1162 1162 ... // common code for cases 3 and 4 1163 1163 // implicit break … … 1167 1167 \lstMakeShortInline@% 1168 1168 \end{cquote} 1169 The target label may be case @default@. 1169 The target label must be below the @fallthrough@, \ie @fallthrough@ cannot form a loop, and the label may not be nested in a control structor, \ie it must be at the same level as the @case@ clauses; 1170 the target label may be case @default@. 1170 1171 1171 1172 Collectively, these control-structure enhancements reduce programmer burden and increase readability and safety. … … 1447 1448 struct T { double m, n; }; 1448 1449 int C::f( T & t ) { $\C{// multiple aggregate parameters}$ 1449 c; i; d; $\C{\color{red}// this- \textgreater.c, this-\textgreater.i, this-\textgreater.d}$1450 c; i; d; $\C{\color{red}// this--{\small\textgreater}.c, this--{\small\textgreater}.i, this--{\small\textgreater}.d}$ 1450 1451 `t.`m; `t.`n; $\C{// must qualify}$ 1451 1452 } … … 1532 1533 S * sp = &sv; 1533 1534 with ( *sp ) { $\C{computed reference}$ 1534 i = 3; j = 4; $\C{\color{red}// sp- {\textgreater}i, sp-{\textgreater}j}$1535 i = 3; j = 4; $\C{\color{red}// sp--{\small\textgreater}i, sp--{\small\textgreater}j}$ 1535 1536 } 1536 1537 i = 2; j = 3; $\C{\color{red}// sr.i, sr.j}$ … … 2525 2526 The \CFA interface wraps GMP functions into operator functions to make programming with multi-precision integers identical to using fixed-sized integers. 2526 2527 The \CFA type name for multi-precision signed-integers is @Int@ and the header file is @gmp@. 2527 The following multi-precision factorial programs contrast using GMP with the \CFA and C interfaces. 2528 \begin{cquote} 2528 Figure~\ref{f:GMPInterface} shows a multi-precision factorial-program contrasting the GMP interface in \CFA and C. 2529 2530 \begin{figure} 2531 \centering 2529 2532 \lstDeleteShortInline@% 2530 2533 \begin{tabular}{@{}l@{\hspace{\parindentlnth}}@{\hspace{\parindentlnth}}l@{}} … … 2557 2560 \end{tabular} 2558 2561 \lstMakeShortInline@% 2559 \end{cquote} 2562 \caption{GMP Interface \CFA versus C} 2563 \label{f:GMPInterface} 2564 \end{figure} 2560 2565 2561 2566 … … 2566 2571 In fact, \CFA's features for generic programming can enable faster runtime execution than idiomatic @void *@-based C code. 2567 2572 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}). 2568 Since all these languages share a subset essentially comprising standard C, maximal-performance benchmarks would show little runtime variance, differing only in length and clarity of source code.2569 A more illustrative benchmarkmeasures the costs of idiomatic usage of each language's features.2573 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. 2574 A more illustrative comparison measures the costs of idiomatic usage of each language's features. 2570 2575 Figure~\ref{fig:BenchmarkTest} shows the \CFA benchmark tests for a generic stack based on a singly linked-list. 2571 The benchmark test is similar for C and \CC.2576 The benchmark test is similar for the other languages. 2572 2577 The experiment uses element types @int@ and @pair(short, char)@, and pushes $N=40M$ elements on a generic stack, copies the stack, clears one of the stacks, and finds the maximum value in the other stack. 2573 2578 … … 2621 2626 \begin{tabular}{rrrrr} 2622 2627 & \CT{C} & \CT{\CFA} & \CT{\CC} & \CT{\CCV} \\ \hline 2623 maximum memory usage (MB) & 10 001 & 2502 & 2503 & 11253\\2628 maximum memory usage (MB) & 10,001 & 2,502 & 2,503 & 11,253 \\ 2624 2629 source code size (lines) & 187 & 186 & 133 & 303 \\ 2625 2630 redundant type annotations (lines) & 25 & 0 & 2 & 16 \\ … … 2645 2650 Raw line-count, however, is a fairly rough measure of code complexity; 2646 2651 another important factor is how much type information the programmer must manually specify, especially where that information is not checked by the compiler. 2647 Such unchecked type information produces a heavier documentation burden and increased potential for runtime bugs, and is much less common in \CFA than C, with its manually specified function pointer arguments and format codes, or \CCV, with its extensive use of un -type-checked downcasts (\eg @object@ to @integer@ when popping a stack, or @object@ to @printable@ when printing the elements of a @pair@).2648 To quantify this , the ``redundant type annotations'' line in Table~\ref{tab:eval} counts the number of lines on which the type of a known variable is re-specified, either as a format specifier, explicit downcast, type-specific function, or by name in a @sizeof@, struct literal, or @new@ expression.2652 Such unchecked type information produces a heavier documentation burden and increased potential for runtime bugs, and is much less common in \CFA than C, with its manually specified function pointer arguments and format codes, or \CCV, with its extensive use of untype-checked downcasts, \eg @object@ to @integer@ when popping a stack. 2653 To quantify this manual typing, the ``redundant type annotations'' line in Table~\ref{tab:eval} counts the number of lines on which the type of a known variable is respecified, either as a format specifier, explicit downcast, type-specific function, or by name in a @sizeof@, struct literal, or @new@ expression. 2649 2654 The \CC benchmark uses two redundant type annotations to create a new stack nodes, while the C and \CCV benchmarks have several such annotations spread throughout their code. 2650 The \CFA benchmark was able to eliminate all redundant type annotations through use of the polymorphic @alloc@ function discussed in Section~\ref{sec:libraries}. 2655 The \CFA benchmark is able to eliminate all redundant type annotations through use of the polymorphic @alloc@ function discussed in Section~\ref{sec:libraries}. 2656 2651 2657 2652 2658 \section{Related Work} 2659 2653 2660 2654 2661 \subsection{Polymorphism} … … 2708 2715 Tuples are a fundamental abstraction in most functional programming languages, such as Standard ML~\cite{sml} and~\cite{Scala}, which decompose tuples using pattern matching. 2709 2716 2717 2710 2718 \subsection{C Extensions} 2711 2719 2712 \CC is the best known C-based language, and similar to \CFA in that both are extensions to C with source and runtime backwards compatibility. 2713 \CC and \CFA have been extensively compared in this paper, but the key difference between their design philosophies is that \CFA aims to be easy for C programmers to understand, by maintaining a procedural paradigm and avoiding complex interactions between extension features. 2720 \CC is the best known C-based language, and is similar to \CFA in that both are extensions to C with source and runtime backwards compatibility. 2721 Specific difference between \CFA and \CC have been identified in prior sections, with a final observation that \CFA has equal or few tokens to express the same notion in several cases. 2722 The key difference between design philosophies is that \CFA is easier for C programmers to understand, by maintaining a procedural paradigm and avoiding complex interactions among extensions. 2714 2723 \CC, on the other hand, has multiple overlapping features (such as the three forms of polymorphism), many of which have complex interactions with its object-oriented design. 2715 As such, though \CC provides good runtime performance and compatibility with C, it has a steep learning curve for even experienced C programmers.2716 2717 There are many other C extension languages with less usage anddramatic changes than \CC.2724 As a result, \CC has a steep learning curve for even experienced C programmers, especially when attempting to maintain performance equivalent to C legacy code. 2725 2726 There are several other C extension-languages with less usage and even more dramatic changes than \CC. 2718 2727 Objective-C and Cyclone are two other extensions to C with different design goals than \CFA, as discussed above. 2719 Many other languages extend C with more focused single features. 2720 CUDA\cite{CUDA}, ispc\cite{Pharr12}, and Sierra\cite{Leissa14} add data-parallel primitives to C or \CC; such features have not yet been added to \CFA, but are not precluded by the design. 2721 Other C extensions attempt to provide a more memory-safe C;\TODO{find some} type-checked polymorphism in \CFA covers many of C's memory-safety holes, but more aggressive approaches such as annotating all pointer types with their nullability are contradictory to \CFA's backwards compatibility goals. 2722 2723 % \subsection{Control Structures / Declarations / Literals} 2724 2725 % Java has default fall through like C/\CC. 2726 % Pascal/Ada/Go/Rust do not have default fall through. 2727 % \Csharp does not have fall through but still requires a break. 2728 % Python uses dictionary mapping. \\ 2729 % \CFA choose is like Rust match. 2730 2731 % Java has labelled break/continue. \\ 2732 % Languages with and without exception handling. 2733 2734 % Alternative C declarations. \\ 2735 % Different references \\ 2736 % Constructors/destructors 2737 2738 % 0/1 Literals \\ 2739 % user defined: D, Objective-C 2728 Other languages extend C with more focused features. 2729 CUDA~\cite{Nickolls08}, ispc~\cite{Pharr12}, and Sierra~\cite{Leissa14} add data-parallel primitives to C or \CC; 2730 such features have not yet been added to \CFA, but are not precluded by the design. 2731 Finaly, some C extensions (or suggested extensions) attempt to provide a more memory-safe C~\cite{Boehm88}; 2732 type-checked polymorphism in \CFA covers several of C's memory-safety holes, but more aggressive approaches such as annotating all pointer types with their nullability are contradictory to \CFA's backwards compatibility goals. 2733 2734 2735 \begin{comment} 2736 \subsection{Control Structures / Declarations / Literals} 2737 2738 Java has default fall through like C/\CC. 2739 Pascal/Ada/Go/Rust do not have default fall through. 2740 \Csharp does not have fall through but still requires a break. 2741 Python uses dictionary mapping. \\ 2742 \CFA choose is like Rust match. 2743 2744 Java has labelled break/continue. \\ 2745 Languages with and without exception handling. 2746 2747 Alternative C declarations. \\ 2748 Different references \\ 2749 Constructors/destructors 2750 2751 0/1 Literals \\ 2752 user defined: D, Objective-C 2753 \end{comment} 2754 2740 2755 2741 2756 \section{Conclusion and Future Work} … … 2784 2799 2785 2800 \smallskip\noindent 2801 C 2802 \begin{cfa}[xleftmargin=2\parindentlnth,aboveskip=0pt,belowskip=0pt] 2803 struct stack_node { 2804 void * value; 2805 struct stack_node * next; 2806 }; 2807 struct stack { struct stack_node* head; }; 2808 struct stack new_stack() { return (struct stack){ NULL }; /***/ } 2809 void copy_stack( struct stack * s, const struct stack * t, void * (*copy)( const void * ) ) { 2810 struct stack_node ** crnt = &s->head; 2811 for ( struct stack_node * next = t->head; next; next = next->next ) { 2812 *crnt = malloc( sizeof(struct stack_node) ); /***/ 2813 (*crnt)->value = copy( next->value ); 2814 crnt = &(*crnt)->next; 2815 } 2816 *crnt = NULL; 2817 } 2818 _Bool stack_empty( const struct stack * s ) { return s->head == NULL; } 2819 void push_stack( struct stack * s, void * value ) { 2820 struct stack_node * n = malloc( sizeof(struct stack_node) ); /***/ 2821 *n = (struct stack_node){ value, s->head }; /***/ 2822 s->head = n; 2823 } 2824 void * pop_stack( struct stack * s ) { 2825 struct stack_node * n = s->head; 2826 s->head = n->next; 2827 void * x = n->value; 2828 free( n ); 2829 return x; 2830 } 2831 void clear_stack( struct stack * s, void (*free_el)( void * ) ) { 2832 for ( struct stack_node * next = s->head; next; ) { 2833 struct stack_node * crnt = next; 2834 next = crnt->next; 2835 free_el( crnt->value ); 2836 free( crnt ); 2837 } 2838 s->head = NULL; 2839 } 2840 \end{cfa} 2841 2842 \medskip\noindent 2786 2843 \CFA 2787 2844 \begin{cfa}[xleftmargin=2\parindentlnth,aboveskip=0pt,belowskip=0pt] … … 2817 2874 stack_node(T) * n = head; 2818 2875 head = n->next; 2819 T x= n->value;2876 T v = n->value; 2820 2877 ^(*n){}; 2821 2878 free( n ); 2822 return x;2879 return v; 2823 2880 } 2824 2881 forall( otype T ) void clear( stack(T) & s ) with( s ) { … … 2840 2897 T value; 2841 2898 node * next; 2842 node( const T & v, node * n = nullptr ) : value( v), next(n) {}2899 node( const T & v, node * n = nullptr ) : value( v), next( n) {} 2843 2900 }; 2844 2901 node * head; 2845 void copy( const stack<T> & o) {2902 void copy( const stack<T> & o) { 2846 2903 node ** crnt = &head; 2847 2904 for ( node * next = o.head;; next; next = next->next ) { … … 2851 2908 *crnt = nullptr; 2852 2909 } 2853 stack() : head( nullptr) {}2854 stack( const stack<T> & o) { copy(o); }2855 stack( stack<T> && o) : head(o.head) { o.head = nullptr; }2910 stack() : head( nullptr) {} 2911 stack( const stack<T> & o) { copy( o); } 2912 stack( stack<T> && o) : head( o.head) { o.head = nullptr; } 2856 2913 ~stack() { clear(); } 2857 stack & operator= ( const stack<T> & o) {2914 stack & operator= ( const stack<T> & o) { 2858 2915 if ( this == &o ) return *this; 2859 2916 clear(); 2860 copy( o);2917 copy( o); 2861 2918 return *this; 2862 2919 } 2863 stack & operator= ( stack<T> && o) {2920 stack & operator= ( stack<T> && o) { 2864 2921 if ( this == &o ) return *this; 2865 2922 head = o.head; … … 2868 2925 } 2869 2926 bool empty() const { return head == nullptr; } 2870 void push( const T & value) { head = new node{ value, head }; /***/ }2927 void push( const T & value) { head = new node{ value, head }; /***/ } 2871 2928 T pop() { 2872 2929 node * n = head; 2873 2930 head = n->next; 2874 T x = std::move( n->value);2931 T x = std::move( n->value); 2875 2932 delete n; 2876 2933 return x; … … 2888 2945 2889 2946 \medskip\noindent 2890 C2891 \begin{cfa}[xleftmargin=2\parindentlnth,aboveskip=0pt,belowskip=0pt]2892 struct stack_node {2893 void * value;2894 struct stack_node * next;2895 };2896 struct stack { struct stack_node* head; };2897 struct stack new_stack() { return (struct stack){ NULL }; /***/ }2898 void copy_stack(struct stack * s, const struct stack * t, void * (*copy)(const void *)) {2899 struct stack_node ** crnt = &s->head;2900 for ( struct stack_node * next = t->head; next; next = next->next ) {2901 *crnt = malloc(sizeof(struct stack_node)); /***/2902 (*crnt)->value = copy(next->value);2903 crnt = &(*crnt)->next;2904 }2905 *crnt = NULL;2906 }2907 _Bool stack_empty(const struct stack * s) { return s->head == NULL; }2908 void push_stack(struct stack * s, void * value) {2909 struct stack_node * n = malloc(sizeof(struct stack_node)); /***/2910 *n = (struct stack_node){ value, s->head }; /***/2911 s->head = n;2912 }2913 void * pop_stack(struct stack * s) {2914 struct stack_node * n = s->head;2915 s->head = n->next;2916 void * x = n->value;2917 free(n);2918 return x;2919 }2920 void clear_stack(struct stack * s, void (*free_el)(void *)) {2921 for ( struct stack_node * next = s->head; next; ) {2922 struct stack_node * crnt = next;2923 next = crnt->next;2924 free_el(crnt->value);2925 free(crnt);2926 }2927 s->head = NULL;2928 }2929 \end{cfa}2930 2931 \medskip\noindent2932 2947 \CCV 2933 2948 \begin{cfa}[xleftmargin=2\parindentlnth,aboveskip=0pt,belowskip=0pt] … … 2939 2954 }; 2940 2955 node* head; 2941 void copy( const stack & o) {2956 void copy( const stack & o ) { 2942 2957 node ** crnt = &head; 2943 2958 for ( node * next = o.head; next; next = next->next ) { … … 2947 2962 *crnt = nullptr; 2948 2963 } 2949 stack() : head( nullptr) {}2950 stack( const stack & o) { copy(o); }2951 stack( stack && o) : head(o.head) { o.head = nullptr; }2964 stack() : head( nullptr ) {} 2965 stack( const stack & o ) { copy( o ); } 2966 stack( stack && o ) : head( o.head ) { o.head = nullptr; } 2952 2967 ~stack() { clear(); } 2953 stack & operator= ( const stack & o) {2968 stack & operator= ( const stack & o ) { 2954 2969 if ( this == &o ) return *this; 2955 2970 clear(); 2956 copy( o);2971 copy( o ); 2957 2972 return *this; 2958 2973 } 2959 stack & operator= ( stack && o) {2974 stack & operator= ( stack && o ) { 2960 2975 if ( this == &o ) return *this; 2961 2976 head = o.head; … … 2964 2979 } 2965 2980 bool empty() const { return head == nullptr; } 2966 void push( const object & value) { head = new node{ value, head }; /***/ }2981 void push( const object & value ) { head = new node{ value, head }; /***/ } 2967 2982 ptr<object> pop() { 2968 2983 node * n = head; 2969 2984 head = n->next; 2970 ptr<object> x = std::move( n->value);2985 ptr<object> x = std::move( n->value ); 2971 2986 delete n; 2972 2987 return x; -
doc/papers/general/evaluation/cfa-stack.c
rdeb52a0 r29db723 2 2 #include "cfa-stack.h" 3 3 4 forall( otype T) struct stack_node {4 forall( otype T ) struct stack_node { 5 5 T value; 6 6 stack_node(T) * next; 7 7 }; 8 8 9 forall( otype T) void ?{}( stack(T) & s ) { (s.head){ 0 }; }9 forall( otype T ) void ?{}( stack(T) & s ) { (s.head){ 0 }; } 10 10 11 forall( otype T) void ?{}( stack(T) & s, stack(T) t ) {11 forall( otype T ) void ?{}( stack(T) & s, stack(T) t ) { 12 12 stack_node(T) ** crnt = &s.head; 13 13 for ( stack_node(T) * next = t.head; next; next = next->next ) { … … 19 19 } 20 20 21 forall( otype T) stack(T) ?=?( stack(T) & s, stack(T) t ) {21 forall( otype T ) stack(T) ?=?( stack(T) & s, stack(T) t ) { 22 22 if ( s.head == t.head ) return s; 23 23 clear( s ); … … 26 26 } 27 27 28 forall( otype T) void ^?{}( stack(T) & s) { clear( s ); }28 forall( otype T ) void ^?{}( stack(T) & s) { clear( s ); } 29 29 30 forall( otype T) _Bool empty( const stack(T) & s ) { return s.head == 0; }30 forall( otype T ) _Bool empty( const stack(T) & s ) { return s.head == 0; } 31 31 32 forall( otype T) void push( stack(T) & s, T value ) with( s ) {33 stack_node(T) * n = alloc();32 forall( otype T ) void push( stack(T) & s, T value ) with( s ) { 33 stack_node(T) * n = alloc(); 34 34 (*n){ value, head }; 35 35 head = n; 36 36 } 37 37 38 forall( otype T) T pop( stack(T) & s ) with( s ) {38 forall( otype T ) T pop( stack(T) & s ) with( s ) { 39 39 stack_node(T) * n = head; 40 40 head = n->next; 41 T x= n->value;41 T v = n->value; 42 42 ^(*n){}; 43 43 free( n ); 44 return x;44 return v; 45 45 } 46 46 47 forall( otype T) void clear( stack(T) & s ) with( s ) {47 forall( otype T ) void clear( stack(T) & s ) with( s ) { 48 48 for ( stack_node(T) * next = head; next; ) { 49 49 stack_node(T) * crnt = next; -
doc/papers/general/evaluation/cfa-stack.h
rdeb52a0 r29db723 1 1 #pragma once 2 2 3 forall( otype T) struct stack_node;4 forall( otype T) struct stack {3 forall( otype T ) struct stack_node; 4 forall( otype T ) struct stack { 5 5 stack_node(T) * head; 6 6 }; 7 7 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);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); 12 12 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 );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 ); -
doc/papers/general/evaluation/timing.gp
rdeb52a0 r29db723 22 22 SCALE=1000 23 23 set ylabel "seconds" 24 set yrange [0:10] 25 26 set label "26.5" at 7.125,10.5 24 27 25 28 # set datafile separator ","
Note: See TracChangeset
for help on using the changeset viewer.