Revert "improve abstraction for AssocList, fix bug in optional else (#315)" (#320)

This reverts commit bf6bb800c4.
This commit is contained in:
Dave Abrahams
2021-03-01 12:26:56 -05:00
committed by GitHub
parent 8b3bb7c5e9
commit f5300a84e5
55 changed files with 7431 additions and 293 deletions
+2 -2
View File
@@ -20,14 +20,14 @@ namespace Carbon {
void PrintAct(Action* act, std::ostream& out) {
switch (act->tag) {
case ActionKind::DeleteTmpAction:
out << "delete_tmp(" << act->u.delete_tmp << ")";
std::cout << "delete_tmp(" << act->u.delete_tmp << ")";
break;
case ActionKind::ExpToLValAction:
out << "exp=>lval";
break;
case ActionKind::LValAction:
case ActionKind::ExpressionAction:
out << *act->u.exp;
PrintExp(act->u.exp);
break;
case ActionKind::StatementAction:
PrintStatement(act->u.stmt, 1);
+1 -1
View File
@@ -10,7 +10,7 @@
#include "executable_semantics/ast/expression.h"
#include "executable_semantics/ast/statement.h"
#include "executable_semantics/interpreter/stack.h"
#include "executable_semantics/interpreter/cons_list.h"
#include "executable_semantics/interpreter/value.h"
namespace Carbon {
+18 -28
View File
@@ -7,42 +7,32 @@
#include <iostream>
#include <list>
#include <optional>
#include <string>
#include "executable_semantics/interpreter/cons_list.h"
namespace Carbon {
template <class K, class V>
class AssocList {
public:
AssocList() { head = nullptr; }
struct AssocList {
AssocList(K k, V v, AssocList* n) : key(k), value(v), next(n) {}
auto Lookup(const K& key) -> std::optional<V> {
if (head == nullptr) {
return std::nullopt;
} else if (head->curr.first == key) {
return head->curr.second;
} else {
auto next = AssocList(head->next);
return next.Lookup(key);
}
}
auto Extend(const K& k, const V& v) -> void {
head = new Cons<std::pair<K, V> >(std::make_pair(k, v), head);
}
auto Extending(const K& k, const V& v) -> AssocList<K, V> {
return AssocList(new Cons<std::pair<K, V> >(std::make_pair(k, v), head));
}
AssocList(Cons<std::pair<K, V> >* h) : head(h) {}
Cons<std::pair<K, V> >* head;
K key;
V value;
AssocList* next;
};
template <class K, class V>
auto Lookup(int line_num, AssocList<K, V>* alist, const K& key,
void (*print_key)(const K&)) -> V {
if (alist == NULL) {
std::cerr << line_num << ": could not find `" << key << "`" << std::endl;
exit(-1);
} else if (alist->key == key) {
return alist->value;
} else {
return Lookup(line_num, alist->next, key, print_key);
}
}
} // namespace Carbon
#endif // EXECUTABLE_SEMANTICS_INTERPRETER_ASSOC_LIST_H_
+6 -1
View File
@@ -7,14 +7,19 @@
namespace Carbon {
template <class T>
struct Stack;
template <class T>
struct Cons {
friend struct Stack<T>;
private:
Cons(T e, Cons* n) : curr(e), next(n) {}
const T curr;
Cons* const next;
private:
// Cons cells are part of a "persistent data structure" and are thus
// immutable.
Cons& operator=(const Cons&) = delete;
+79 -110
View File
@@ -19,12 +19,10 @@
namespace Carbon {
extern bool tracing_output;
State* state = nullptr;
auto PatternMatch(Value* pat, Value* val, Env, std::list<std::string>*, int)
-> std::optional<Env>;
auto PatternMatch(Value* pat, Value* val, Env*, std::list<std::string>*, int)
-> Env*;
void HandleValue();
template <class T>
@@ -136,12 +134,12 @@ void KillValue(Value* val) {
}
}
void PrintEnv(Env env, std::ostream& out) {
if (env.head) {
std::cout << env.head->curr.first << ": ";
PrintValue(state->heap[env.head->curr.second], out);
void PrintEnv(Env* env, std::ostream& out) {
if (env) {
std::cout << env->key << ": ";
PrintValue(state->heap[env->value], out);
std::cout << ", ";
PrintEnv(Env(env.head->next), out);
PrintEnv(env->next, out);
}
}
@@ -175,7 +173,7 @@ void PrintHeap(const std::vector<Value*>& heap, std::ostream& out) {
}
}
auto CurrentEnv(State* state) -> Env {
auto CurrentEnv(State* state) -> Env* {
Frame* frame = state->stack.Top();
return frame->scopes.Top()->env;
}
@@ -253,7 +251,7 @@ auto EvalPrim(Operator op, const std::vector<Value*>& args, int line_num)
}
}
Env globals;
Env* globals;
void InitGlobals(std::list<Declaration>* fs) {
globals = nullptr;
@@ -262,7 +260,7 @@ void InitGlobals(std::list<Declaration>* fs) {
}
}
auto ChoiceDeclaration::InitGlobals(Env& globals) const -> void {
auto ChoiceDeclaration::InitGlobals(Env*& globals) const -> void {
auto alts = new VarValues();
for (auto kv : alternatives) {
auto t = ToType(line_num, InterpExp(nullptr, kv.second));
@@ -270,10 +268,10 @@ auto ChoiceDeclaration::InitGlobals(Env& globals) const -> void {
}
auto ct = MakeChoiceTypeVal(name, alts);
auto a = AllocateValue(ct);
globals.Extend(name, a);
globals = new Env(name, a, globals);
}
auto StructDeclaration::InitGlobals(Env& globals) const -> void {
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();
@@ -289,15 +287,15 @@ auto StructDeclaration::InitGlobals(Env& globals) const -> void {
}
auto st = MakeStructTypeVal(*definition.name, fields, methods);
auto a = AllocateValue(st);
globals.Extend(*definition.name, a);
globals = new Env(*definition.name, a, globals);
}
auto FunctionDeclaration::InitGlobals(Env& globals) const -> void {
Env env;
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.Extend(definition->name, a);
globals = new Env(definition->name, a, globals);
}
// { S, H} -> { { C, E, F} :: S, H}
@@ -310,7 +308,7 @@ void CallFunction(int line_num, std::vector<Value*> operas, State* state) {
case ValKind::FunV: {
// Bind arguments to parameters
std::list<std::string> params;
auto env = PatternMatch(operas[0]->u.fun.param, operas[1], globals,
Env* env = PatternMatch(operas[0]->u.fun.param, operas[1], globals,
&params, line_num);
if (!env) {
std::cerr << "internal error in call_function, pattern match failed"
@@ -318,7 +316,7 @@ void CallFunction(int line_num, std::vector<Value*> operas, State* state) {
exit(-1);
}
// Create the new frame and push it on the stack
auto* scope = new Scope(*env, params);
auto* scope = new Scope(env, params);
auto* frame = new Frame(*operas[0]->u.fun.name, Stack(scope),
Stack(MakeStmtAct(operas[0]->u.fun.body)));
state->stack.Push(frame);
@@ -349,12 +347,8 @@ void CallFunction(int line_num, std::vector<Value*> operas, State* state) {
void KillScope(int line_num, Scope* scope) {
for (const auto& l : scope->locals) {
auto a = scope->env.Lookup(l);
if (a) {
KillValue(state->heap[*a]);
} else {
std::cerr << "internal error" << std::endl;
}
Address a = Lookup(line_num, scope->env, l, PrintErrorString);
KillValue(state->heap[a]);
}
}
@@ -393,23 +387,26 @@ auto ToValue(Expression* value) -> Value* {
case ExpressionKind::FunctionT:
// Instead add to patterns?
default:
std::cerr << "internal error in to_value, didn't expect " << *value
<< std::endl;
std::cerr << "internal error in to_value, didn't expect ";
PrintExp(value);
std::cerr << std::endl;
exit(-1);
}
}
// Returns 0 if the value doesn't match the pattern.
auto PatternMatch(Value* p, Value* v, Env env, std::list<std::string>* vars,
int line_num) -> std::optional<Env> {
if (tracing_output) {
std::cout << "pattern_match(" << *p << ", " << *v << ")" << std::endl;
}
auto PatternMatch(Value* p, Value* v, Env* env, std::list<std::string>* vars,
int line_num) -> Env* {
std::cout << "pattern_match(";
PrintValue(p, std::cout);
std::cout << ", ";
PrintValue(v, std::cout);
std::cout << ")" << std::endl;
switch (p->tag) {
case ValKind::VarPatV: {
Address a = AllocateValue(CopyVal(v, line_num));
vars->push_back(*p->u.var_pat.name);
return env.Extending(*p->u.var_pat.name, a);
return new Env(*p->u.var_pat.name, a, env);
}
case ValKind::TupleV:
switch (v->tag) {
@@ -427,12 +424,8 @@ auto PatternMatch(Value* p, Value* v, Env env, std::list<std::string>* vars,
std::cerr << std::endl;
exit(-1);
}
auto result = PatternMatch(state->heap[elt.second], state->heap[*a],
env, vars, line_num);
if (result)
env = *result;
else
return env;
env = PatternMatch(state->heap[elt.second], state->heap[*a], env,
vars, line_num);
}
return env;
}
@@ -448,9 +441,10 @@ auto PatternMatch(Value* p, Value* v, Env env, std::list<std::string>* vars,
case ValKind::AltV: {
if (*p->u.alt.choice_name != *v->u.alt.choice_name ||
*p->u.alt.alt_name != *v->u.alt.alt_name) {
return std::nullopt;
return nullptr;
}
return PatternMatch(p->u.alt.arg, v->u.alt.arg, env, vars, line_num);
env = PatternMatch(p->u.alt.arg, v->u.alt.arg, env, vars, line_num);
return env;
}
default:
std::cerr
@@ -462,24 +456,20 @@ auto PatternMatch(Value* p, Value* v, Env env, std::list<std::string>* vars,
}
case ValKind::FunctionTV:
switch (v->tag) {
case ValKind::FunctionTV: {
auto result = PatternMatch(p->u.fun_type.param, v->u.fun_type.param,
env, vars, line_num);
if (result)
env = *result;
else
return env;
return PatternMatch(p->u.fun_type.ret, v->u.fun_type.ret, env, vars,
line_num);
}
case ValKind::FunctionTV:
env = PatternMatch(p->u.fun_type.param, v->u.fun_type.param, env,
vars, line_num);
env = PatternMatch(p->u.fun_type.ret, v->u.fun_type.ret, env, vars,
line_num);
return env;
default:
return std::nullopt;
return nullptr;
}
default:
if (ValueEqual(p, v, line_num)) {
return env;
} else {
return std::nullopt;
return nullptr;
}
}
}
@@ -555,24 +545,19 @@ void StepLvalue() {
Frame* frame = state->stack.Top();
Action* act = frame->todo.Top();
Expression* exp = act->u.exp;
if (tracing_output) {
std::cout << "--- step lvalue " << *exp << " --->" << std::endl;
}
std::cout << "--- step lvalue ";
PrintExp(exp);
std::cout << " --->" << std::endl;
switch (exp->tag) {
case ExpressionKind::Variable: {
// { {x :: C, E, F} :: S, H}
// -> { {E(x) :: C, E, F} :: S, H}
auto a = CurrentEnv(state).Lookup(*(exp->u.variable.name));
if (a) {
Value* v = MakePtrVal(*a);
CheckAlive(v, exp->line_num);
frame->todo.Pop();
frame->todo.Push(MakeValAct(v));
} else {
std::cerr << exp->line_num << ": variable " << *(exp->u.variable.name)
<< " is not defined" << std::endl;
exit(-1);
}
Address a = Lookup(exp->line_num, CurrentEnv(state),
*(exp->u.variable.name), PrintErrorString);
Value* v = MakePtrVal(a);
CheckAlive(v, exp->line_num);
frame->todo.Pop();
frame->todo.Push(MakeValAct(v));
break;
}
case ExpressionKind::GetField: {
@@ -620,9 +605,9 @@ void StepExp() {
Frame* frame = state->stack.Top();
Action* act = frame->todo.Top();
Expression* exp = act->u.exp;
if (tracing_output) {
std::cout << "--- step exp " << *exp << " --->" << std::endl;
}
std::cout << "--- step exp ";
PrintExp(exp);
std::cout << " --->" << std::endl;
switch (exp->tag) {
case ExpressionKind::PatternVariable: {
frame->todo.Push(MakeExpAct(exp->u.pattern_variable.type));
@@ -657,16 +642,11 @@ void StepExp() {
}
case ExpressionKind::Variable: {
// { {x :: C, E, F} :: S, H} -> { {H(E(x)) :: C, E, F} :: S, H}
auto a = CurrentEnv(state).Lookup(*(exp->u.variable.name));
if (a) {
Value* v = state->heap[*a];
frame->todo.Pop(1);
frame->todo.Push(MakeValAct(v));
} else {
std::cerr << exp->line_num << ": variable " << *(exp->u.variable.name)
<< " is not defined " << std::endl;
exit(-1);
}
Address a = Lookup(exp->line_num, CurrentEnv(state),
*(exp->u.variable.name), PrintErrorString);
Value* v = state->heap[a];
frame->todo.Pop(1);
frame->todo.Push(MakeValAct(v));
break;
}
case ExpressionKind::Integer:
@@ -767,11 +747,9 @@ void StepStmt() {
Action* act = frame->todo.Top();
Statement* const stmt = act->u.stmt;
assert(stmt != nullptr && "null statement!");
if (tracing_output) {
std::cout << "--- step stmt ";
PrintStatement(stmt, 1);
std::cout << " --->" << std::endl;
}
std::cout << "--- step stmt ";
PrintStatement(stmt, 1);
std::cout << " --->" << std::endl;
switch (stmt->tag) {
case StatementKind::Match:
// { { (match (e) ...) :: C, E, F} :: S, H}
@@ -940,11 +918,11 @@ void HandleValue() {
act->results.push_back(val_act->u.val);
act->pos++;
if (tracing_output) {
std::cout << "--- handle value " << *val_act->u.val << " with ";
PrintAct(act, std::cout);
std::cout << " --->" << std::endl;
}
std::cout << "--- handle value ";
PrintValue(val_act->u.val, std::cout);
std::cout << " with ";
PrintAct(act, std::cout);
std::cout << " --->" << std::endl;
switch (act->tag) {
case ActionKind::DeleteTmpAction: {
@@ -1163,17 +1141,16 @@ void HandleValue() {
Value* v = act->results[0];
Value* p = act->results[1];
// Address a = AllocateValue(CopyVal(v));
auto result =
frame->scopes.Top()->env =
PatternMatch(p, v, frame->scopes.Top()->env,
&frame->scopes.Top()->locals, stmt->line_num);
if (!result) {
if (!frame->scopes.Top()->env) {
std::cerr
<< stmt->line_num
<< ": internal error in variable definition, match failed"
<< std::endl;
exit(-1);
}
frame->scopes.Top()->env = *result;
frame->todo.Pop(2);
}
break;
@@ -1200,14 +1177,12 @@ void HandleValue() {
// -> { { then_stmt :: C, E, F } :: S, H}
frame->todo.Pop(2);
frame->todo.Push(MakeStmtAct(stmt->u.if_stmt.then_stmt));
} else if (stmt->u.if_stmt.else_stmt) {
} else {
// { {false :: if ([]) then_stmt else else_stmt :: C, E, F} ::
// S, H}
// -> { { else_stmt :: C, E, F } :: S, H}
frame->todo.Pop(2);
frame->todo.Push(MakeStmtAct(stmt->u.if_stmt.else_stmt));
} else {
frame->todo.Pop(2);
}
break;
case StatementKind::While:
@@ -1257,9 +1232,9 @@ void HandleValue() {
auto pat = act->results[clause_num + 1];
auto env = CurrentEnv(state);
std::list<std::string> vars;
auto new_env = PatternMatch(pat, v, env, &vars, stmt->line_num);
Env* new_env = PatternMatch(pat, v, env, &vars, stmt->line_num);
if (new_env) { // we have a match, start the body
auto* new_scope = new Scope(*new_env, vars);
auto* new_scope = new Scope(new_env, vars);
frame->scopes.Push(new_scope);
Statement* body_block = MakeBlock(stmt->line_num, c->second);
Action* body_act = MakeStmtAct(body_block);
@@ -1348,9 +1323,7 @@ void Step() {
// Interpret the whole porogram.
auto InterpProgram(std::list<Declaration>* fs) -> int {
state = new State(); // Runtime state.
if (tracing_output) {
std::cout << "********** initializing globals **********" << std::endl;
}
std::cout << "********** initializing globals **********" << std::endl;
InitGlobals(fs);
Expression* arg =
@@ -1361,25 +1334,21 @@ auto InterpProgram(std::list<Declaration>* fs) -> int {
auto* frame = new Frame("top", Stack(scope), todo);
state->stack = Stack(frame);
if (tracing_output) {
std::cout << "********** calling main function **********" << std::endl;
PrintState(std::cout);
}
std::cout << "********** calling main function **********" << std::endl;
PrintState(std::cout);
while (state->stack.CountExceeds(1) ||
state->stack.Top()->todo.CountExceeds(1) ||
state->stack.Top()->todo.Top()->tag != ActionKind::ValAction) {
Step();
if (tracing_output) {
PrintState(std::cout);
}
PrintState(std::cout);
}
Value* v = state->stack.Top()->todo.Top()->u.val;
return ValToInt(v, 0);
}
// Interpret an expression at compile-time.
auto InterpExp(Env env, Expression* e) -> Value* {
auto InterpExp(Env* env, Expression* e) -> Value* {
auto todo = Stack(MakeExpAct(e));
auto* scope = new Scope(env, std::list<std::string>());
auto* frame = new Frame("InterpExp", Stack(scope), todo);
@@ -22,8 +22,8 @@ using Env = AssocList<std::string, Address>;
/***** Scopes *****/
struct Scope {
Scope(Env e, std::list<std::string> l) : env(e), locals(std::move(l)) {}
Env env;
Scope(Env* e, std::list<std::string> l) : env(e), locals(std::move(l)) {}
Env* env;
std::list<std::string> locals;
};
@@ -45,7 +45,7 @@ struct State {
extern State* state;
void PrintEnv(Env env);
void PrintEnv(Env* env);
auto AllocateValue(Value* v) -> Address;
auto CopyVal(Value* val, int line_num) -> Value*;
auto ToInteger(Value* v) -> int;
@@ -53,7 +53,7 @@ auto ToInteger(Value* v) -> int;
/***** Interpreters *****/
auto InterpProgram(std::list<Declaration>* fs) -> int;
auto InterpExp(Env env, Expression* e) -> Value*;
auto InterpExp(Env* env, Expression* e) -> Value*;
} // namespace Carbon
-2
View File
@@ -9,8 +9,6 @@
#include <cstddef>
#include <iterator>
#include "executable_semantics/interpreter/cons_list.h"
namespace Carbon {
/// A persistent stack data structure.
+31 -33
View File
@@ -32,12 +32,12 @@ void ExpectType(int line_num, const std::string& context, Value* expected,
void PrintErrorString(const std::string& s) { std::cerr << s; }
void PrintTypeEnv(TypeEnv env, std::ostream& out) {
if (env.head) {
out << env.head->curr.first << ": ";
PrintValue(env.head->curr.second, out);
void PrintTypeEnv(TypeEnv* env, std::ostream& out) {
if (env) {
out << env->key << ": ";
PrintValue(env->value, out);
out << ", ";
PrintTypeEnv(TypeEnv(env.head->next), out);
PrintTypeEnv(env->next, out);
}
}
@@ -139,7 +139,7 @@ auto ReifyType(Value* t, int line_num) -> Expression* {
// and it is used to implement `auto`, otherwise it is null.
// context says what kind of position this expression is nested in,
// whether it's a position that expects a value, a pattern, or a type.
auto TypeCheckExp(Expression* e, TypeEnv env, Env ct_env, Value* expected,
auto TypeCheckExp(Expression* e, TypeEnv* env, Env* ct_env, Value* expected,
TCContext context) -> TCResult {
switch (e->tag) {
case ExpressionKind::PatternVariable: {
@@ -164,7 +164,8 @@ auto TypeCheckExp(Expression* e, TypeEnv env, Env ct_env, Value* expected,
}
auto new_e = MakeVarPat(e->line_num, *e->u.pattern_variable.name,
ReifyType(t, e->line_num));
return TCResult(new_e, t, env.Extending(*e->u.pattern_variable.name, t));
return TCResult(new_e, t,
new TypeEnv(*e->u.pattern_variable.name, t, env));
}
case ExpressionKind::Index: {
auto res = TypeCheckExp(e->u.get_field.aggregate, env, ct_env, nullptr,
@@ -274,20 +275,16 @@ auto TypeCheckExp(Expression* e, TypeEnv env, Env ct_env, Value* expected,
default:
std::cerr << e->line_num
<< ": compilation error in field access, expected a struct"
<< std::endl
<< *e << std::endl;
<< std::endl;
PrintExp(e);
std::cerr << std::endl;
exit(-1);
}
}
case ExpressionKind::Variable: {
auto t = env.Lookup(*(e->u.variable.name));
if (t) {
return TCResult(e, *t, env);
} else {
std::cerr << e->line_num << ": variable " << *(e->u.variable.name)
<< " is not defined" << std::endl;
exit(-1);
}
auto t =
Lookup(e->line_num, env, *(e->u.variable.name), PrintErrorString);
return TCResult(e, t, env);
}
case ExpressionKind::Integer:
return TCResult(e, MakeIntTypeVal(), env);
@@ -349,8 +346,9 @@ auto TypeCheckExp(Expression* e, TypeEnv env, Env ct_env, Value* expected,
default: {
std::cerr << e->line_num
<< ": compilation error in call, expected a function"
<< std::endl
<< *e << std::endl;
<< std::endl;
PrintExp(e);
std::cerr << std::endl;
exit(-1);
}
}
@@ -389,7 +387,7 @@ auto TypeCheckExp(Expression* e, TypeEnv env, Env ct_env, Value* expected,
}
auto TypecheckCase(Value* expected, Expression* pat, Statement* body,
TypeEnv env, Env ct_env, Value* ret_type)
TypeEnv* env, Env* ct_env, Value* ret_type)
-> std::pair<Expression*, Statement*> {
auto pat_res =
TypeCheckExp(pat, env, ct_env, expected, TCContext::PatternContext);
@@ -404,7 +402,7 @@ auto TypecheckCase(Value* expected, Expression* pat, Statement* body,
// It is the declared return type of the enclosing function definition.
// If the return type is "auto", then the return type is inferred from
// the first return statement.
auto TypeCheckStmt(Statement* s, TypeEnv env, Env ct_env, Value* ret_type)
auto TypeCheckStmt(Statement* s, TypeEnv* env, Env* ct_env, Value* ret_type)
-> TCStatement {
if (!s) {
return TCStatement(s, env);
@@ -568,7 +566,7 @@ auto CheckOrEnsureReturn(Statement* stmt, bool void_return, int line_num)
}
}
auto TypeCheckFunDef(const FunctionDefinition* f, TypeEnv env, Env ct_env)
auto TypeCheckFunDef(const FunctionDefinition* f, TypeEnv* env, Env* ct_env)
-> struct FunctionDefinition* {
auto param_res = TypeCheckExp(f->param_pattern, env, ct_env, nullptr,
TCContext::PatternContext);
@@ -585,7 +583,7 @@ auto TypeCheckFunDef(const FunctionDefinition* f, TypeEnv env, Env ct_env)
f->param_pattern, body);
}
auto TypeOfFunDef(TypeEnv env, Env ct_env, const FunctionDefinition* fun_def)
auto TypeOfFunDef(TypeEnv* env, Env* ct_env, const FunctionDefinition* fun_def)
-> Value* {
auto param_res = TypeCheckExp(fun_def->param_pattern, env, ct_env, nullptr,
TCContext::PatternContext);
@@ -598,7 +596,7 @@ auto TypeOfFunDef(TypeEnv env, Env ct_env, const FunctionDefinition* fun_def)
return MakeFunTypeVal(param_type, ret);
}
auto TypeOfStructDef(const StructDefinition* sd, TypeEnv /*env*/, Env ct_top)
auto TypeOfStructDef(const StructDefinition* sd, TypeEnv* /*env*/, Env* ct_top)
-> Value* {
auto fields = new VarValues();
auto methods = new VarValues();
@@ -619,7 +617,7 @@ auto StructDeclaration::Name() const -> std::string { return *definition.name; }
auto ChoiceDeclaration::Name() const -> std::string { return name; }
auto StructDeclaration::TypeChecked(TypeEnv env, Env ct_env) const
auto StructDeclaration::TypeChecked(TypeEnv* env, Env* ct_env) const
-> Declaration {
auto fields = new std::list<Member*>();
for (auto& m : *definition.members) {
@@ -631,17 +629,17 @@ auto StructDeclaration::TypeChecked(TypeEnv env, Env ct_env) const
return StructDeclaration(definition.line_num, *definition.name, fields);
}
auto FunctionDeclaration::TypeChecked(TypeEnv env, Env ct_env) const
auto FunctionDeclaration::TypeChecked(TypeEnv* env, Env* ct_env) const
-> Declaration {
return FunctionDeclaration(TypeCheckFunDef(definition, env, ct_env));
}
auto ChoiceDeclaration::TypeChecked(TypeEnv env, Env ct_env) const
auto ChoiceDeclaration::TypeChecked(TypeEnv* env, Env* ct_env) const
-> Declaration {
return *this; // TODO.
}
auto TopLevel(std::list<Declaration>* fs) -> std::pair<TypeEnv, Env> {
auto TopLevel(std::list<Declaration>* fs) -> std::pair<TypeEnv*, Env*> {
ExecutionEnvironment tops = {nullptr, nullptr};
bool found_main = false;
@@ -662,16 +660,16 @@ auto TopLevel(std::list<Declaration>* fs) -> std::pair<TypeEnv, Env> {
auto FunctionDeclaration::TopLevel(ExecutionEnvironment& tops) const -> void {
auto t = TypeOfFunDef(tops.first, tops.second, definition);
tops.first.Extend(Name(), t);
tops.first = new TypeEnv(Name(), t, tops.first);
}
auto StructDeclaration::TopLevel(ExecutionEnvironment& tops) const -> void {
auto st = TypeOfStructDef(&definition, tops.first, tops.second);
Address a = AllocateValue(st);
tops.second.Extend(Name(), a); // Is this obsolete?
tops.second = new Env(Name(), a, tops.second); // Is this obsolete?
auto params = MakeTupleTypeVal(st->u.struct_type.fields);
auto fun_ty = MakeFunTypeVal(params, st);
tops.first.Extend(Name(), fun_ty);
tops.first = new TypeEnv(Name(), fun_ty, tops.first);
}
auto ChoiceDeclaration::TopLevel(ExecutionEnvironment& tops) const -> void {
@@ -682,8 +680,8 @@ auto ChoiceDeclaration::TopLevel(ExecutionEnvironment& tops) const -> void {
}
auto ct = MakeChoiceTypeVal(name, alts);
Address a = AllocateValue(ct);
tops.second.Extend(Name(), a); // Is this obsolete?
tops.first.Extend(Name(), ct);
tops.second = new Env(Name(), a, tops.second); // Is this obsolete?
tops.first = new TypeEnv(Name(), ct, tops.first);
}
} // namespace Carbon
+10 -10
View File
@@ -16,37 +16,37 @@ namespace Carbon {
using TypeEnv = AssocList<std::string, Value*>;
void PrintTypeEnv(TypeEnv env);
void PrintTypeEnv(TypeEnv* env);
enum class TCContext { ValueContext, PatternContext, TypeContext };
struct TCResult {
TCResult(Expression* e, Value* t, TypeEnv env) : exp(e), type(t), env(env) {}
TCResult(Expression* e, Value* t, TypeEnv* env) : exp(e), type(t), env(env) {}
Expression* exp;
Value* type;
TypeEnv env;
TypeEnv* env;
};
struct TCStatement {
TCStatement(Statement* s, TypeEnv e) : stmt(s), env(e) {}
TCStatement(Statement* s, TypeEnv* e) : stmt(s), env(e) {}
Statement* stmt;
TypeEnv env;
TypeEnv* env;
};
auto ToType(int line_num, Value* val) -> Value*;
auto TypeCheckExp(Expression* e, TypeEnv env, Env ct_env, Value* expected,
auto TypeCheckExp(Expression* e, TypeEnv* env, Env* ct_env, Value* expected,
TCContext context) -> TCResult;
auto TypeCheckStmt(Statement*, TypeEnv, Env, Value*) -> TCStatement;
auto TypeCheckStmt(Statement*, TypeEnv*, Env*, Value*) -> TCStatement;
auto TypeCheckFunDef(struct FunctionDefinition*, TypeEnv)
auto TypeCheckFunDef(struct FunctionDefinition*, TypeEnv*)
-> struct FunctionDefinition*;
auto TopLevel(std::list<Declaration>* fs) -> std::pair<TypeEnv, Env>;
auto TopLevel(std::list<Declaration>* fs) -> std::pair<TypeEnv*, Env*>;
void PrintErrorString(const std::string& s);
} // namespace Carbon
@@ -314,11 +314,6 @@ void PrintValue(Value* val, std::ostream& out) {
}
}
auto operator<<(std::ostream& out, const Value& v) -> std::ostream& {
PrintValue((Value*)&v, out);
return out;
}
auto TypeEqual(Value* t1, Value* t2) -> bool {
if (t1->tag != t2->tag) {
return false;
-2
View File
@@ -5,7 +5,6 @@
#ifndef EXECUTABLE_SEMANTICS_INTERPRETER_VALUE_H_
#define EXECUTABLE_SEMANTICS_INTERPRETER_VALUE_H_
#include <iostream>
#include <list>
#include <vector>
@@ -128,7 +127,6 @@ auto MakeVoidTypeVal() -> Value*;
auto MakeChoiceTypeVal(std::string name, VarValues* alts) -> Value*;
void PrintValue(Value* val, std::ostream& out);
auto operator<<(std::ostream& os, const Value& v) -> std::ostream&;
auto TypeEqual(Value* t1, Value* t2) -> bool;
auto ValueEqual(Value* v1, Value* v2, int line_num) -> bool;