Value semantics for Declaration. (#313)

This change creates an unpleasant amount of boilerplate where `Declaration` is declared, in exchange for being able to—very pleasantly—treat it as a simple value that composes with other values everywhere it is used. Applying this technique broadly will pay off in code comprehensibility; once it has been done for all things being new'd, pointers disappear and references are only needed as an idiomatic approximation of inout. The unpleasant code grows only when new polymorphic operations are added, and then only a bit, and is an idiom whose details can readily be ignored once in place. The pleasant code pervades the codebase.

Too bad we don't have existential types in C++ ;-)
This commit is contained in:
Dave Abrahams
2021-02-28 11:29:38 -08:00
committed by GitHub
parent 2afbfd6146
commit 102ea3ccaf
8 changed files with 112 additions and 48 deletions
@@ -253,10 +253,10 @@ auto EvalPrim(Operator op, const std::vector<Value*>& args, int line_num)
Env* globals;
void InitGlobals(std::list<const Declaration*>* fs) {
void InitGlobals(std::list<Declaration>* fs) {
globals = nullptr;
for (auto d : *fs) {
d->InitGlobals(globals);
for (auto const& d : *fs) {
d.InitGlobals(globals);
}
}
@@ -1321,7 +1321,7 @@ void Step() {
}
// Interpret the whole porogram.
auto InterpProgram(std::list<const Declaration*>* fs) -> int {
auto InterpProgram(std::list<Declaration>* fs) -> int {
state = new State(); // Runtime state.
std::cout << "********** initializing globals **********" << std::endl;
InitGlobals(fs);