Changes in / [5b643ea:8da3cc4d]
- Location:
- doc/theses/mike_brooks_MMath
- Files:
-
- 2 deleted
- 3 edited
-
array.tex (modified) (4 diffs)
-
programs/hello-accordion.cfa (modified) (3 diffs)
-
programs/school1 (deleted)
-
programs/school2 (deleted)
-
string.tex (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
doc/theses/mike_brooks_MMath/array.tex
r5b643ea r8da3cc4d 205 205 Orthogonally, the new @array@ type works with \CFA's generic types, providing argument safety and the associated implicit communication of array length. 206 206 Specifically, \CFA allows aggregate types to be generalized with multiple type parameters, including parameterized element types and lengths. 207 Doing so gives a refinement of C's ``flexible array member'' pattern, allowing nesting structures with array members anywhere within thestructures.207 Doing so gives a refinement of C's ``flexible array member'' pattern, allowing nesting structures with array members anywhere within other structures. 208 208 \lstinput{10-15}{hello-accordion.cfa} 209 This structure's layout has the starting offset of @ studentIds@ varying in generic parameter @C@, and the offset of @preferences@ varying in both generic parameters.210 For a function that operates on a @ School@ structure, the type system handles this memory layouttransparently.209 This structure's layout has the starting offset of @municipalities@ varying in @NprovTerty@, and the offset of @total_pt@ and @total_mun@ varying in both generic parameters. 210 For a function that operates on a @CanPop@ structure, the type system handles this variation transparently. 211 211 \lstinput{40-45}{hello-accordion.cfa} 212 \VRef[Figure]{f:checkHarness} shows the @ School@ harness and results with different array sizes, where multidimensional arrays are discussed next.212 \VRef[Figure]{f:checkHarness} shows the @CanPop@ harness and results with different array sizes, if the municipalities changed after a census. 213 213 214 214 \begin{figure} 215 % super hack to get this to line up 216 \begin{tabular}{@{}ll@{\hspace{25pt}}l@{}} 217 \begin{tabular}{@{}p{3.25in}@{}} 218 \lstinput{60-66}{hello-accordion.cfa} 219 \vspace*{-3pt} 220 \lstinput{73-80}{hello-accordion.cfa} 221 \end{tabular} 222 & 223 \raisebox{0.32\totalheight}{% 224 \lstinput{85-93}{hello-accordion.cfa} 225 }% 226 & 227 \lstinput{95-109}{hello-accordion.cfa} 228 \end{tabular} 229 \caption{\lstinline{school} Harness and Output} 215 \lstinput{60-68}{hello-accordion.cfa} 216 \lstinput{70-75}{hello-accordion.cfa} 217 \caption{\lstinline{check} Harness} 230 218 \label{f:checkHarness} 231 219 \end{figure} … … 500 488 From there, @x[all]@ itself is simply a two-dimensional array, in the strict C sense, of these building blocks. 501 489 An atom (like the bottommost value, @x[all][3][2]@), is the contained value (in the square box) 502 and a lie about its size (the left diagonalabove it, growing upward).490 and a lie about its size (the wedge above it, growing upward). 503 491 An array of these atoms (like the intermediate @x[all][3]@) is just a contiguous arrangement of them, done according to their size; 504 492 call such an array a column. 505 493 A column is almost ready to be arranged into a matrix; 506 494 it is the \emph{contained value} of the next-level building block, but another lie about size is required. 507 At first, an atom needs to be arranged as if it were bigger, but now a column needs to be arranged as if it is smaller (the left diagonalabove it, shrinking upward).495 At first, an atom needs to be arranged as if it were bigger, but now a column needs to be arranged as if it is smaller (the wedge above it, shrinking upward). 508 496 These lying columns, arranged contiguously according to their size (as announced) form the matrix @x[all]@. 509 497 Because @x[all]@ takes indices, first for the fine stride, then for the coarse stride, it achieves the requirement of representing the transpose of @x@. … … 514 502 compared with where analogous rows appear when the row-level option is presented for @x@. 515 503 516 For example, in \lstinline{x[all]}, the shaded band touches atoms 2.0, 2.1, 2.2, 2.3, 1.4, 1.5 and 1.6 (left diagonal). 504 \PAB{I don't understand this paragraph: These size lies create an appearance of overlap. 505 For example, in \lstinline{x[all]}, the shaded band touches atoms 2.0, 2.1, 2.2, 2.3, 1.4, 1.5 and 1.6. 517 506 But only the atom 2.3 is storing its value there. 518 The rest are lying about (conflicting) claims on this location, but never exercising these alleged claims. 507 The rest are lying about (conflicting) claims on this location, but never exercising these alleged claims.} 519 508 520 509 Lying is implemented as casting. … … 522 511 This structure uses one type in its internal field declaration and offers a different type as the return of its subscript operator. 523 512 The field within is a plain-C array of the fictional type, which is 7 floats long for @x[all][3][2]@ and 1 float long for @x[all][3]@. 524 The subscript operator presents what is really inside, by casting to the type below the left diagonalof the lie.513 The subscript operator presents what is really inside, by casting to the type below the wedge of the lie. 525 514 526 515 % Does x[all] have to lie too? The picture currently glosses over how it it advertises a size of 7 floats. I'm leaving that as an edge case benignly misrepresented in the picture. Edge cases only have to be handled right in the code. -
doc/theses/mike_brooks_MMath/programs/hello-accordion.cfa
r5b643ea r8da3cc4d 8 8 9 9 10 forall( [C], [S] ) $\C{// Class size, Students in class}$11 struct School{12 @array( int, C )@ classIds; $\C{// nested VLAs}$13 @array( int, S )@ studentIds;14 @array( int, C, S )@ preferences; $\C{// multidimensional}$10 forall( T, @[NprovTerty]@, @[Nmunicipalities]@ ) 11 struct CanPop { 12 array( T, @NprovTerty@ ) provTerty; $\C{// nested VLA}$ 13 array( T, @Nmunicipalities@ ) municipalities; $\C{// nested VLA}$ 14 int total_pt, total_mun; 15 15 }; 16 17 16 18 17 19 18 // TODO: understand (fix?) why these are needed (autogen seems to be failing ... is typeof as struct member nayok?) 20 19 21 forall( [C], [S] )22 void ?{}( School( C, S) & this ) {}20 forall( T, [NprovTerty], [Nmunicipalities] ) 21 void ?{}( T &, CanPop( T, NprovTerty, Nmunicipalities ) & this ) {} 23 22 24 forall( [C], [S] )25 void ^?{}( School( C, S) & this ) {}23 forall( T &, [NprovTerty], [Nmunicipalities] ) 24 void ^?{}( CanPop( T, NprovTerty, Nmunicipalities ) & this ) {} 26 25 27 26 … … 38 37 39 38 40 forall( [C], [S] ) 41 void init( @School( C, S ) & classes@, int class, int student, int pref ) with( classes ) { 42 classIds[class] = class; $\C{// handle dynamic offsets of fields within structure}$ 43 studentIds[student] = student; 44 preferences[class][student] = pref; 39 40 forall( T, [NprovTerty], [Nmunicipalities] ) 41 void check( CanPop( T, NprovTerty, Nmunicipalities ) & pop ) with( pop ) { 42 total_pt = total_mun = 0; 43 for ( i; NprovTerty ) total_pt += provTerty[i]; 44 for ( i; Nmunicipalities ) total_mun += municipalities[i]; 45 45 } 46 46 … … 58 58 59 59 60 int main() { 61 int classes, students; 62 sin | classes | students; 63 @School( classes, students ) school;@ 64 int class, student, preference; 65 // read data into school calling init 66 // for each student's class/preferences 67 try { 68 for ( ) { 69 sin | class | student | preference; 70 init( school, class, student, preference ); 71 } 72 } catch( end_of_file * ) {} 73 for ( s; students ) { 74 sout | "student" | s | nonl; 75 for ( c; classes ) { 76 sout | school.preferences[c][s] | nonl; 77 } 78 sout | nl; 79 } 60 int main( int argc, char * argv[] ) { 61 const int npt = ato( argv[1] ), nmun = ato( argv[2] ); 62 @CanPop( int, npt, nmun ) pop;@ 63 // read in population numbers 64 @check( pop );@ 65 sout | setlocale( LC_NUMERIC, getenv( "LANG" ) ); 66 sout | "Total province/territory:" | pop.total_pt; 67 sout | "Total municipalities:" | pop.total_mun; 80 68 } 81 82 83 84 69 /* 85 $\$$ cat school1 86 2 2 87 0 0 1 88 1 0 7 89 0 1 12 90 1 1 13 91 $\$$ a.out < school1 92 student 0 1 7 93 student 1 12 13 94 95 $\$$ cat school2 96 3 3 97 0 0 1 98 1 0 7 99 2 0 8 100 0 1 12 101 1 1 13 102 2 1 14 103 0 2 26 104 1 2 27 105 2 2 28 106 $\$$ a.out < school2 107 student 0 1 7 8 108 student 1 12 13 14 109 student 2 26 27 28 70 $\$$ ./a.out 13 3573 71 Total province/territory: 36,991,981 72 Total municipalities: 36,991,981 73 $\$$ ./a.out 13 3654 74 Total province/territory: 36,991,981 75 Total municipalities: 36,991,981 110 76 */ 111 77 -
doc/theses/mike_brooks_MMath/string.tex
r5b643ea r8da3cc4d 1 1 \chapter{String} 2 2 3 This chapter presents my work on designing and building a modern string type in \CFA. 4 The discussion starts with examples of interesting string problems, followed by examples of how these issues are solved in my design. 5 6 7 \s ection{Logical overlap}3 4 5 6 7 \subsection{Logical overlap} 8 8 9 9 \input{sharing-demo.tex} … … 20 20 \subsection{RAII limitations} 21 21 22 Earlier work on \CFA [to cite Schluntz] implemented the feature of constructors and destructors. A constructor is a user-defined function that runs implicitly, when control passes an object's declaration, while a destructor runs at the exit of the declaration's lexical scope. The feature allows programmers to assume that, whenever a runtime object of a certain type is accessible, the system called one of the programmer's const ructor functions on that object, and a matching destructor call will happen in the future. The feature helps programmers know that their programs' invariants obtain.23 24 The purposes of such invariants go beyond ensuring authentic values for the bits inside the object. These invariants can track occurrences of the managed objects in other data structures. Reference counting is a typical application of the latter invariant type. With a reference-counting smart pointer, the const ructor and destructor \emph{of the pointer type} track the life cycles of occurrences of these pointers, by incrementing and decrementing a counter (usually) on the referent object, that is, they maintain a that is state separate from the objects to whose life cycles they are attached. Both the \CC and \CFA RAII systems ares powerful enough to achieve such reference counting.25 26 The \CC RAII system supports a more advanced application. A life cycle function has access to the object under management, by location; constructors and destuctors receive a @this@ parameter providing its memory address. A lifecycle-function implementation can then add its objects to a collection upon creation, and remove them at destruction. A modulue that provides such objects, by using and encapsulating such a collection, can traverse the collection at relevant times, to keep the objects ``good.'' Then, if you are the user of such an module, declaring an object of its type means not only receiving an authentically ``good'' value at initialization, but receiving a subscription to a service that will keep the value ``good'' until you are done with it.22 Earlier work on \CFA [to cite Schluntz] implemented the feature of constructors and destructors. A constructor is a user-defined function that runs implicitly, when control passes an object's declaration, while a destructor runs at the exit of the declaration's lexical scope. The feature allows programmers to assume that, whenever a runtime object of a certain type is accessible, the system called one of the programmer's constuctor functions on that object, and a matching destructor call will happen in the future. The feature helps programmers know that their programs' invariants obtain. 23 24 The purposes of such invariants go beyond ensuring authentic values for the bits inside the object. These invariants can track occurrences of the managed objects in other data structures. Reference counting is a typical application of the latter invariant type. With a reference-counting smart pointer, the consturctor and destructor \emph{of the pointer type} track the lifecycles of occurrences of these pointers, by incrementing and decrementing a counter (ususally) on the referent object, that is, they maintain a that is state separate from the objects to whose lifecycles they are attached. Both the \CC and \CFA RAII systems ares powerful enough to achive such reference counting. 25 26 The \CC RAII system supports a more advanced application. A lifecycle function has access to the object under managamanet, by location; constructors and destuctors receive a @this@ parameter providing its memory address. A lifecycle-function implementation can then add its objects to a collection upon creation, and remove them at destruction. A modulue that provides such objects, by using and encapsulating such a collection, can traverse the collection at relevant times, to keep the objects ``good.'' Then, if you are the user of such an module, declaring an object of its type means not only receiving an authentically ``good'' value at initialization, but receiving a subscription to a service that will keep the value ``good'' until you are done with it. 27 27 28 28 In many cases, the relationship between memory location and lifecycle is simple. But with stack-allocated objects being used as parameters and returns, there is a sender version in one stack frame and a receiver version in another. \CC is able to treat those versions as distinct objects and guarantee a copy-constructor call for communicating the value from one to the other. This ability has implications on the language's calling convention. Consider an ordinary function @void f( Vehicle x )@, which receives an aggregate by value. If the type @Vehicle@ has custom lifecycle functions, then a call to a user-provided copy constructor occurs, after the caller evaluates its argument expression, after the callee's stack frame exists, with room for its variable @x@ (which is the location that the copy-constructor must target), but before the user-provided body of @f@ begins executing. \CC achieves this ordering by changing the function signature, in the compiled form, to pass-by-reference and having the callee invoke the copy constructor in its preamble. On the other hand, if @Vehicle@ is a simple structure then the C calling convention is applied as the code originally appeared, that is, the callsite implementation code performs a bitwise copy from the caller's expression result, into the callee's x.
Note:
See TracChangeset
for help on using the changeset viewer.