Commit 58e92174 by Graham Lee

Enforce command-query separation in the ChunkFinder class.

parent aa851293
......@@ -64,7 +64,9 @@ The main function also needs the definition of each of the module interfaces. It
@
We will look at each of the important modules in turn, before coming back to the intricacies of the main function. The first important task it does, once it has worked out that it has the information to do it, is get the list of chunks from the \texttt{ChunkFiler}.
<<find chunks>>=
id chunks = [[ChunkFinder new] chunksInDocument:file named:basename];
id chunkFinder = [ChunkFinder new];
[chunkFinder findChunksInDocument:file named:basename];
id chunks = [chunkFinder discoveredChunks];
@
Chunks are instances of classes descended from the \texttt{Chunk} class. While it knows how to be a chunk, it does not know how to represent itself as \LaTeX, or whether it contains code, and so on. Those questions are answered by specific subclasses, shown in Figure \ref{fig:chunks.puml} (some attributes and methods are elided from the diagram).
{{chunks.puml}}=
......@@ -223,7 +225,8 @@ The \texttt{ChunkFinder} uses these boundaries to split the \texttt{gloom} sourc
@interface ChunkFinder : NSObject
- chunkBoundaries;
- chunksInDocument:aDocument named:aName;
- (void)findChunksInDocument:aDocument named:aName;
- discoveredChunks;
@end
<<ChunkFinder.m>>=
......@@ -234,13 +237,24 @@ The \texttt{ChunkFinder} uses these boundaries to split the \texttt{gloom} sourc
#import "FigureBoundary.h"
@implementation ChunkFinder
<<ChunkFinder instance variables>>
<<chunk boundaries>>
<<chunks in document>>
<<find chunks in document>>
<<discovered chunks>>
@end
@
The \texttt{ChunkFinder} works on a string that contains the \textsc{gloom} source, and the name of its document. It stores results in a list of chunks.
<<ChunkFinder instance variables>>=
{
id document;
id name;
id chunks;
}
@
The \texttt{ChunkFinder}'s list of chunk boundaries is where it ``knows'' about each of the different boundaries.
<<chunk boundaries>>=
- chunkBoundaries
......@@ -248,14 +262,17 @@ The \texttt{ChunkFinder}'s list of chunk boundaries is where it ``knows'' about
return @[[CodeBoundary new], [DocumentationBoundary new], [FigureBoundary new]];
}
@
It is the \texttt{chunksInDocument:named:} method that actually builds the model: a list of chunks. It starts by creating the "opening chunk", then reads each line in the file. If it matches a chunk boundary, then a new chunk is created. If not, then the line is added to the current chunk.
<<chunks in document>>=
- chunksInDocument:aDocument named:aName
The \texttt{-findChunksInDocument:named:} takes copies of the parameters to be the chunk finder's instance variables. It can then work on them without concern that they will be modified from outside. It is this method that actually builds the model: a list of chunks. It starts by creating the "opening chunk", then reads each line in the file. If it matches a chunk boundary, then a new chunk is created. If not, then the line is added to the current chunk.
<<find chunks in document>>=
- (void)findChunksInDocument:aDocument named:aName
{
document = [aDocument copy];
name = [aName copy];
id boundaries = [self chunkBoundaries];
<<create chunk indices>>
<<create opening chunk>>
[aDocument enumerateLinesUsingBlock:^(NSString * _Nonnull line, BOOL * _Nonnull stop) {
[document enumerateLinesUsingBlock:^(NSString * _Nonnull line, BOOL * _Nonnull stop) {
__block id changeChunk = nil;
[boundaries enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
changeChunk = [obj changedChunkAtLine:line];
......@@ -270,21 +287,27 @@ It is the \texttt{chunksInDocument:named:} method that actually builds the model
}
}];
[chunks makeObjectsPerformSelector:@selector(findInclusions:) withObject:chunksByName];
return [chunks copy];
}
@
Two indices are maintained: the list of chunks seen so far, and a dictionary of chunks by name that is used for resolving inclusions (a code chunk can include another code chunk by enclosing its name in guillemets, <<like this>>).
<<create chunk indices>>=
id chunks = [NSMutableArray new];
chunks = [NSMutableArray array];
id chunksByName = [NSMutableDictionary new];
@
The initial chunk is a special documentation chunk called the \emph{opening chunk}. This comes in helpful when weaving. A cursor is created, and set to the opening chunk.
<<create opening chunk>>=
id docChunk = [Chunk openingChunkWithName:aName];
chunksByName[aName] = docChunk;
id docChunk = [Chunk openingChunkWithName:name];
chunksByName[name] = docChunk;
[chunks addObject:docChunk];
__block id currentChunk = docChunk;
@
The query for returning discovered chunks returns a copy of the list of chunks that was built.
<<discovered chunks>>=
- discoveredChunks
{
return [chunks copy];
}
@
The chunk classes are listed below. The sections relevant to constructing the model are shown in-place in the source files, anything relevant to weaving, tangling or enmeshing is left out for now.
<<Chunk.h>>=
#import <Foundation/Foundation.h>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment