mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-10-03 20:35:49 +01:00
[executable semantics] class-ify Declaration (#307)
* [executable semantics] class-ify Declaration NFC (no functional change). Proof of concept that we can simplify code by replacing unions with safer, more regular types. Hand-rolled existentials (type-erasing CoW wrappers) are a follow-on step that will further simplify usage. Began adding `const` where possible, and replacing `std::string*` with `std::string`. Most `const`s can disappear as we replace reference semantics with value semantics, but in the meantime it's an important step in the right direction.
This commit is contained in:
@@ -252,55 +252,49 @@ auto EvalPrim(Operator op, const std::vector<Value*>& args, int line_num)
|
||||
|
||||
Env* globals;
|
||||
|
||||
void InitGlobals(std::list<Declaration*>* fs) {
|
||||
void InitGlobals(std::list<const Declaration*>* fs) {
|
||||
globals = nullptr;
|
||||
for (auto& iter : *fs) {
|
||||
switch (iter->tag) {
|
||||
case DeclarationKind::ChoiceDeclaration: {
|
||||
auto d = iter;
|
||||
auto alts = new VarValues();
|
||||
for (auto i = d->u.choice_def.alternatives->begin();
|
||||
i != d->u.choice_def.alternatives->end(); ++i) {
|
||||
auto t =
|
||||
ToType(d->u.choice_def.line_num, InterpExp(nullptr, i->second));
|
||||
alts->push_back(make_pair(i->first, t));
|
||||
}
|
||||
auto ct = MakeChoiceTypeVal(d->u.choice_def.name, alts);
|
||||
auto a = AllocateValue(ct);
|
||||
globals = new Env(*d->u.choice_def.name, a, globals);
|
||||
break;
|
||||
}
|
||||
case DeclarationKind::StructDeclaration: {
|
||||
auto d = iter;
|
||||
auto fields = new VarValues();
|
||||
auto methods = new VarValues();
|
||||
for (auto i = d->u.struct_def->members->begin();
|
||||
i != d->u.struct_def->members->end(); ++i) {
|
||||
switch ((*i)->tag) {
|
||||
case MemberKind::FieldMember: {
|
||||
auto t = ToType(d->u.struct_def->line_num,
|
||||
InterpExp(nullptr, (*i)->u.field.type));
|
||||
fields->push_back(make_pair(*(*i)->u.field.name, t));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
auto st = MakeStructTypeVal(*d->u.struct_def->name, fields, methods);
|
||||
auto a = AllocateValue(st);
|
||||
globals = new Env(*d->u.struct_def->name, a, globals);
|
||||
break;
|
||||
}
|
||||
case DeclarationKind::FunctionDeclaration: {
|
||||
struct FunctionDefinition* fun = iter->u.fun_def;
|
||||
Env* env = nullptr;
|
||||
auto pt = InterpExp(env, fun->param_pattern);
|
||||
auto f = MakeFunVal(fun->name, pt, fun->body);
|
||||
Address a = AllocateValue(f);
|
||||
globals = new Env(fun->name, a, globals);
|
||||
for (auto d : *fs) {
|
||||
d->InitGlobals(globals);
|
||||
}
|
||||
}
|
||||
|
||||
auto ChoiceDeclaration::InitGlobals(Env*& globals) const -> void {
|
||||
auto alts = new VarValues();
|
||||
for (auto kv : alternatives) {
|
||||
auto t = ToType(line_num, InterpExp(nullptr, kv.second));
|
||||
alts->push_back(make_pair(kv.first, t));
|
||||
}
|
||||
auto ct = MakeChoiceTypeVal(name, alts);
|
||||
auto a = AllocateValue(ct);
|
||||
globals = new Env(name, a, globals);
|
||||
}
|
||||
|
||||
auto StructDeclaration::InitGlobals(Env*& globals) const -> void {
|
||||
auto fields = new VarValues();
|
||||
auto methods = new VarValues();
|
||||
for (auto i = definition.members->begin(); i != definition.members->end();
|
||||
++i) {
|
||||
switch ((*i)->tag) {
|
||||
case MemberKind::FieldMember: {
|
||||
auto t =
|
||||
ToType(definition.line_num, InterpExp(nullptr, (*i)->u.field.type));
|
||||
fields->push_back(make_pair(*(*i)->u.field.name, t));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
auto st = MakeStructTypeVal(*definition.name, fields, methods);
|
||||
auto a = AllocateValue(st);
|
||||
globals = new Env(*definition.name, a, globals);
|
||||
}
|
||||
|
||||
auto FunctionDeclaration::InitGlobals(Env*& globals) const -> void {
|
||||
Env* env = nullptr;
|
||||
auto pt = InterpExp(env, definition->param_pattern);
|
||||
auto f = MakeFunVal(definition->name, pt, definition->body);
|
||||
Address a = AllocateValue(f);
|
||||
globals = new Env(definition->name, a, globals);
|
||||
}
|
||||
|
||||
// { S, H} -> { { C, E, F} :: S, H}
|
||||
@@ -1325,7 +1319,7 @@ void Step() {
|
||||
}
|
||||
|
||||
// Interpret the whole porogram.
|
||||
auto InterpProgram(std::list<Declaration*>* fs) -> int {
|
||||
auto InterpProgram(std::list<const Declaration*>* fs) -> int {
|
||||
state = new State(); // Runtime state.
|
||||
std::cout << "********** initializing globals **********" << std::endl;
|
||||
InitGlobals(fs);
|
||||
|
||||
Reference in New Issue
Block a user