A library is useless if no one knows how to use it. Step 6 focuses on creating a "Driver Program" (or Client Application) that uses our library to do something real.
#include "scanner.h"
#include "tokenizer.h"
#include "stats.h"We include the Public API. Notice we do NOT include .c files. We only need the promises (headers).
In C, we often use a pattern called Dependency Injection manually.
Scanner scanner;
scanner_init(&scanner, input);
Tokenizer tokenizer;
tokenizer_init(&tokenizer, &scanner); // Inject scanner into tokenizerThe Tokenizer needs a source of characters. Instead of hardcoding it to read a file, we "inject" the scanner. This makes the Tokenizer flexible.
while (token.type != TOKEN_END) {
// Process token...
}This is the standard Consumption Loop. You assume the stream of tokens is infinite until you hit the special TOKEN_END signal.
When checking if your code works, you need two steps:
- Compile: Convert
demo.ctodemo.o. It needs standard headers. - Link: Combine
demo.o+libtxtengine.a->demo.exe.- The Linker resolves symbols like
scanner_nextby looking inside the library.
- The Linker resolves symbols like
- Client Code: How strictly separated the user code is from the library code.
- Integration: Putting all the modules together to solve a problem.