mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-10-04 08:11:05 +01:00
Private unions (#492)
* changed union of Statement to be private * changed the union in Expression to be private * changed union in Value to be private * changed AST constructors to be static methods * updates to syntax unit tests
This commit is contained in:
@@ -67,54 +67,59 @@ auto CopyVal(const Value* val, int line_num) -> const Value* {
|
||||
switch (val->tag) {
|
||||
case ValKind::TupleV: {
|
||||
auto* elements = new std::vector<TupleElement>();
|
||||
for (const TupleElement& element : *val->u.tuple.elements) {
|
||||
for (const TupleElement& element : *val->GetTuple().elements) {
|
||||
const Value* new_element =
|
||||
CopyVal(state->heap.Read(element.address, line_num), line_num);
|
||||
Address new_address = state->heap.AllocateValue(new_element);
|
||||
elements->push_back({.name = element.name, .address = new_address});
|
||||
}
|
||||
return MakeTupleVal(elements);
|
||||
return Value::MakeTupleVal(elements);
|
||||
}
|
||||
case ValKind::AltV: {
|
||||
const Value* arg =
|
||||
CopyVal(state->heap.Read(val->u.alt.argument, line_num), line_num);
|
||||
const Value* arg = CopyVal(
|
||||
state->heap.Read(val->GetAlternative().argument, line_num), line_num);
|
||||
Address argument_address = state->heap.AllocateValue(arg);
|
||||
return MakeAltVal(*val->u.alt.alt_name, *val->u.alt.choice_name,
|
||||
argument_address);
|
||||
return Value::MakeAltVal(*val->GetAlternative().alt_name,
|
||||
*val->GetAlternative().choice_name,
|
||||
argument_address);
|
||||
}
|
||||
case ValKind::StructV: {
|
||||
const Value* inits = CopyVal(val->u.struct_val.inits, line_num);
|
||||
return MakeStructVal(val->u.struct_val.type, inits);
|
||||
const Value* inits = CopyVal(val->GetStruct().inits, line_num);
|
||||
return Value::MakeStructVal(val->GetStruct().type, inits);
|
||||
}
|
||||
case ValKind::IntV:
|
||||
return MakeIntVal(val->u.integer);
|
||||
return Value::MakeIntVal(val->GetInteger());
|
||||
case ValKind::BoolV:
|
||||
return MakeBoolVal(val->u.boolean);
|
||||
return Value::MakeBoolVal(val->GetBoolean());
|
||||
case ValKind::FunV:
|
||||
return MakeFunVal(*val->u.fun.name, val->u.fun.param, val->u.fun.body);
|
||||
return Value::MakeFunVal(*val->GetFunction().name,
|
||||
val->GetFunction().param,
|
||||
val->GetFunction().body);
|
||||
case ValKind::PtrV:
|
||||
return MakePtrVal(val->u.ptr);
|
||||
return Value::MakePtrVal(val->GetPointer());
|
||||
case ValKind::ContinuationV:
|
||||
// Copying a continuation is "shallow".
|
||||
return val;
|
||||
case ValKind::FunctionTV:
|
||||
return MakeFunTypeVal(CopyVal(val->u.fun_type.param, line_num),
|
||||
CopyVal(val->u.fun_type.ret, line_num));
|
||||
return Value::MakeFunTypeVal(
|
||||
CopyVal(val->GetFunctionType().param, line_num),
|
||||
CopyVal(val->GetFunctionType().ret, line_num));
|
||||
|
||||
case ValKind::PointerTV:
|
||||
return MakePtrTypeVal(CopyVal(val->u.ptr_type.type, line_num));
|
||||
return Value::MakePtrTypeVal(
|
||||
CopyVal(val->GetPointerType().type, line_num));
|
||||
case ValKind::IntTV:
|
||||
return MakeIntTypeVal();
|
||||
return Value::MakeIntTypeVal();
|
||||
case ValKind::BoolTV:
|
||||
return MakeBoolTypeVal();
|
||||
return Value::MakeBoolTypeVal();
|
||||
case ValKind::TypeTV:
|
||||
return MakeTypeTypeVal();
|
||||
return Value::MakeTypeTypeVal();
|
||||
case ValKind::VarTV:
|
||||
return MakeVarTypeVal(*val->u.var_type);
|
||||
return Value::MakeVarTypeVal(*val->GetVariableType());
|
||||
case ValKind::AutoTV:
|
||||
return MakeAutoTypeVal();
|
||||
return Value::MakeAutoTypeVal();
|
||||
case ValKind::ContinuationTV:
|
||||
return MakeContinuationTypeVal();
|
||||
return Value::MakeContinuationTypeVal();
|
||||
case ValKind::StructTV:
|
||||
case ValKind::ChoiceTV:
|
||||
case ValKind::VarPatV:
|
||||
@@ -127,13 +132,13 @@ auto CopyVal(const Value* val, int line_num) -> const Value* {
|
||||
void Heap::DeallocateSubObjects(const Value* val) {
|
||||
switch (val->tag) {
|
||||
case ValKind::AltV:
|
||||
Deallocate(val->u.alt.argument);
|
||||
Deallocate(val->GetAlternative().argument);
|
||||
break;
|
||||
case ValKind::StructV:
|
||||
DeallocateSubObjects(val->u.struct_val.inits);
|
||||
DeallocateSubObjects(val->GetStruct().inits);
|
||||
break;
|
||||
case ValKind::TupleV:
|
||||
for (const TupleElement& element : *val->u.tuple.elements) {
|
||||
for (const TupleElement& element : *val->GetTuple().elements) {
|
||||
Deallocate(element.address);
|
||||
}
|
||||
break;
|
||||
@@ -221,7 +226,7 @@ void PrintState(std::ostream& out) {
|
||||
auto ValToInt(const Value* v, int line_num) -> int {
|
||||
switch (v->tag) {
|
||||
case ValKind::IntV:
|
||||
return v->u.integer;
|
||||
return v->GetInteger();
|
||||
default:
|
||||
std::cerr << line_num << ": runtime error: expected an integer"
|
||||
<< std::endl;
|
||||
@@ -232,7 +237,7 @@ auto ValToInt(const Value* v, int line_num) -> int {
|
||||
auto ValToBool(const Value* v, int line_num) -> int {
|
||||
switch (v->tag) {
|
||||
case ValKind::BoolV:
|
||||
return v->u.boolean;
|
||||
return v->GetBoolean();
|
||||
default:
|
||||
std::cerr << "runtime type error: expected a Boolean" << std::endl;
|
||||
exit(-1);
|
||||
@@ -242,7 +247,7 @@ auto ValToBool(const Value* v, int line_num) -> int {
|
||||
auto ValToPtr(const Value* v, int line_num) -> Address {
|
||||
switch (v->tag) {
|
||||
case ValKind::PtrV:
|
||||
return v->u.ptr;
|
||||
return v->GetPointer();
|
||||
default:
|
||||
std::cerr << "runtime type error: expected a pointer, not ";
|
||||
PrintValue(v, std::cerr);
|
||||
@@ -257,7 +262,7 @@ auto ValToPtr(const Value* v, int line_num) -> Address {
|
||||
auto ContinuationToVector(const Value* continuation, int sourceLocation)
|
||||
-> std::vector<Frame*> {
|
||||
if (continuation->tag == ValKind::ContinuationV) {
|
||||
return *continuation->u.continuation.stack;
|
||||
return *continuation->GetContinuation().stack;
|
||||
} else {
|
||||
std::cerr << sourceLocation << ": runtime error: expected an integer"
|
||||
<< std::endl;
|
||||
@@ -269,23 +274,23 @@ auto EvalPrim(Operator op, const std::vector<const Value*>& args, int line_num)
|
||||
-> const Value* {
|
||||
switch (op) {
|
||||
case Operator::Neg:
|
||||
return MakeIntVal(-ValToInt(args[0], line_num));
|
||||
return Value::MakeIntVal(-ValToInt(args[0], line_num));
|
||||
case Operator::Add:
|
||||
return MakeIntVal(ValToInt(args[0], line_num) +
|
||||
ValToInt(args[1], line_num));
|
||||
return Value::MakeIntVal(ValToInt(args[0], line_num) +
|
||||
ValToInt(args[1], line_num));
|
||||
case Operator::Sub:
|
||||
return MakeIntVal(ValToInt(args[0], line_num) -
|
||||
ValToInt(args[1], line_num));
|
||||
return Value::MakeIntVal(ValToInt(args[0], line_num) -
|
||||
ValToInt(args[1], line_num));
|
||||
case Operator::Not:
|
||||
return MakeBoolVal(!ValToBool(args[0], line_num));
|
||||
return Value::MakeBoolVal(!ValToBool(args[0], line_num));
|
||||
case Operator::And:
|
||||
return MakeBoolVal(ValToBool(args[0], line_num) &&
|
||||
ValToBool(args[1], line_num));
|
||||
return Value::MakeBoolVal(ValToBool(args[0], line_num) &&
|
||||
ValToBool(args[1], line_num));
|
||||
case Operator::Or:
|
||||
return MakeBoolVal(ValToBool(args[0], line_num) ||
|
||||
ValToBool(args[1], line_num));
|
||||
return Value::MakeBoolVal(ValToBool(args[0], line_num) ||
|
||||
ValToBool(args[1], line_num));
|
||||
case Operator::Eq:
|
||||
return MakeBoolVal(ValueEqual(args[0], args[1], line_num));
|
||||
return Value::MakeBoolVal(ValueEqual(args[0], args[1], line_num));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -304,7 +309,7 @@ auto ChoiceDeclaration::InitGlobals(Env& globals) const -> void {
|
||||
auto t = InterpExp(Env(), kv.second);
|
||||
alts->push_back(make_pair(kv.first, t));
|
||||
}
|
||||
auto ct = MakeChoiceTypeVal(name, alts);
|
||||
auto ct = Value::MakeChoiceTypeVal(name, alts);
|
||||
auto a = state->heap.AllocateValue(ct);
|
||||
globals.Set(name, a);
|
||||
}
|
||||
@@ -322,7 +327,7 @@ auto StructDeclaration::InitGlobals(Env& globals) const -> void {
|
||||
}
|
||||
}
|
||||
}
|
||||
auto st = MakeStructTypeVal(*definition.name, fields, methods);
|
||||
auto st = Value::MakeStructTypeVal(*definition.name, fields, methods);
|
||||
auto a = state->heap.AllocateValue(st);
|
||||
globals.Set(*definition.name, a);
|
||||
}
|
||||
@@ -330,7 +335,7 @@ auto StructDeclaration::InitGlobals(Env& globals) const -> void {
|
||||
auto FunctionDeclaration::InitGlobals(Env& globals) const -> void {
|
||||
Env values;
|
||||
auto pt = InterpExp(values, definition->param_pattern);
|
||||
auto f = MakeFunVal(definition->name, pt, definition->body);
|
||||
auto f = Value::MakeFunVal(definition->name, pt, definition->body);
|
||||
Address a = state->heap.AllocateValue(f);
|
||||
globals.Set(definition->name, a);
|
||||
}
|
||||
@@ -353,8 +358,9 @@ void CallFunction(int line_num, std::vector<const Value*> operas,
|
||||
case ValKind::FunV: {
|
||||
// Bind arguments to parameters
|
||||
std::list<std::string> params;
|
||||
std::optional<Env> matches = PatternMatch(
|
||||
operas[0]->u.fun.param, operas[1], globals, ¶ms, line_num);
|
||||
std::optional<Env> matches =
|
||||
PatternMatch(operas[0]->GetFunction().param, operas[1], globals,
|
||||
¶ms, line_num);
|
||||
if (!matches) {
|
||||
std::cerr << "internal error in call_function, pattern match failed"
|
||||
<< std::endl;
|
||||
@@ -362,23 +368,25 @@ void CallFunction(int line_num, std::vector<const Value*> operas,
|
||||
}
|
||||
// Create the new frame and push it on the stack
|
||||
auto* scope = new Scope(*matches, params);
|
||||
auto* frame = new Frame(*operas[0]->u.fun.name, Stack(scope),
|
||||
Stack(MakeStmtAct(operas[0]->u.fun.body)));
|
||||
auto* frame =
|
||||
new Frame(*operas[0]->GetFunction().name, Stack(scope),
|
||||
Stack(MakeStmtAct(operas[0]->GetFunction().body)));
|
||||
state->stack.Push(frame);
|
||||
break;
|
||||
}
|
||||
case ValKind::StructTV: {
|
||||
const Value* arg = CopyVal(operas[1], line_num);
|
||||
const Value* sv = MakeStructVal(operas[0], arg);
|
||||
const Value* sv = Value::MakeStructVal(operas[0], arg);
|
||||
Frame* frame = state->stack.Top();
|
||||
frame->todo.Push(MakeValAct(sv));
|
||||
break;
|
||||
}
|
||||
case ValKind::AltConsV: {
|
||||
const Value* arg = CopyVal(operas[1], line_num);
|
||||
const Value* av = MakeAltVal(*operas[0]->u.alt_cons.alt_name,
|
||||
*operas[0]->u.alt_cons.choice_name,
|
||||
state->heap.AllocateValue(arg));
|
||||
const Value* av =
|
||||
Value::MakeAltVal(*operas[0]->GetAlternativeConstructor().alt_name,
|
||||
*operas[0]->GetAlternativeConstructor().choice_name,
|
||||
state->heap.AllocateValue(arg));
|
||||
Frame* frame = state->stack.Top();
|
||||
frame->todo.Push(MakeValAct(av));
|
||||
break;
|
||||
@@ -412,12 +420,12 @@ void CreateTuple(Frame* frame, Action* act, const Expression* /*exp*/) {
|
||||
// { { (v1,...,vn) :: C, E, F} :: S, H}
|
||||
// -> { { `(v1,...,vn) :: C, E, F} :: S, H}
|
||||
auto elements = new std::vector<TupleElement>();
|
||||
auto f = act->u.exp->u.tuple.fields->begin();
|
||||
auto f = act->u.exp->GetTuple().fields->begin();
|
||||
for (auto i = act->results.begin(); i != act->results.end(); ++i, ++f) {
|
||||
Address a = state->heap.AllocateValue(*i); // copy?
|
||||
elements->push_back({.name = f->name, .address = a});
|
||||
}
|
||||
const Value* tv = MakeTupleVal(elements);
|
||||
const Value* tv = Value::MakeTupleVal(elements);
|
||||
frame->todo.Pop(1);
|
||||
frame->todo.Push(MakeValAct(tv));
|
||||
}
|
||||
@@ -433,19 +441,20 @@ auto PatternMatch(const Value* p, const Value* v, Env values,
|
||||
switch (p->tag) {
|
||||
case ValKind::VarPatV: {
|
||||
Address a = state->heap.AllocateValue(CopyVal(v, line_num));
|
||||
vars->push_back(*p->u.var_pat.name);
|
||||
values.Set(*p->u.var_pat.name, a);
|
||||
vars->push_back(*p->GetVariablePattern().name);
|
||||
values.Set(*p->GetVariablePattern().name, a);
|
||||
return values;
|
||||
}
|
||||
case ValKind::TupleV:
|
||||
switch (v->tag) {
|
||||
case ValKind::TupleV: {
|
||||
if (p->u.tuple.elements->size() != v->u.tuple.elements->size()) {
|
||||
if (p->GetTuple().elements->size() !=
|
||||
v->GetTuple().elements->size()) {
|
||||
std::cerr << "runtime error: arity mismatch in tuple pattern match"
|
||||
<< std::endl;
|
||||
exit(-1);
|
||||
}
|
||||
for (const TupleElement& element : *p->u.tuple.elements) {
|
||||
for (const TupleElement& element : *p->GetTuple().elements) {
|
||||
auto a = FindTupleField(element.name, v);
|
||||
if (a == std::nullopt) {
|
||||
std::cerr << "runtime error: field " << element.name << "not in ";
|
||||
@@ -473,14 +482,15 @@ auto PatternMatch(const Value* p, const Value* v, Env values,
|
||||
case ValKind::AltV:
|
||||
switch (v->tag) {
|
||||
case ValKind::AltV: {
|
||||
if (*p->u.alt.choice_name != *v->u.alt.choice_name ||
|
||||
*p->u.alt.alt_name != *v->u.alt.alt_name) {
|
||||
if (*p->GetAlternative().choice_name !=
|
||||
*v->GetAlternative().choice_name ||
|
||||
*p->GetAlternative().alt_name != *v->GetAlternative().alt_name) {
|
||||
return std::nullopt;
|
||||
}
|
||||
std::optional<Env> matches =
|
||||
PatternMatch(state->heap.Read(p->u.alt.argument, line_num),
|
||||
state->heap.Read(v->u.alt.argument, line_num),
|
||||
values, vars, line_num);
|
||||
std::optional<Env> matches = PatternMatch(
|
||||
state->heap.Read(p->GetAlternative().argument, line_num),
|
||||
state->heap.Read(v->GetAlternative().argument, line_num), values,
|
||||
vars, line_num);
|
||||
if (!matches) {
|
||||
return std::nullopt;
|
||||
}
|
||||
@@ -497,13 +507,15 @@ auto PatternMatch(const Value* p, const Value* v, Env values,
|
||||
case ValKind::FunctionTV:
|
||||
switch (v->tag) {
|
||||
case ValKind::FunctionTV: {
|
||||
std::optional<Env> matches = PatternMatch(
|
||||
p->u.fun_type.param, v->u.fun_type.param, values, vars, line_num);
|
||||
std::optional<Env> matches =
|
||||
PatternMatch(p->GetFunctionType().param,
|
||||
v->GetFunctionType().param, values, vars, line_num);
|
||||
if (!matches) {
|
||||
return std::nullopt;
|
||||
}
|
||||
return PatternMatch(p->u.fun_type.ret, v->u.fun_type.ret, *matches,
|
||||
vars, line_num);
|
||||
return PatternMatch(p->GetFunctionType().ret,
|
||||
v->GetFunctionType().ret, *matches, vars,
|
||||
line_num);
|
||||
}
|
||||
default:
|
||||
return std::nullopt;
|
||||
@@ -526,12 +538,13 @@ void PatternAssignment(const Value* pat, const Value* val, int line_num) {
|
||||
case ValKind::TupleV: {
|
||||
switch (val->tag) {
|
||||
case ValKind::TupleV: {
|
||||
if (pat->u.tuple.elements->size() != val->u.tuple.elements->size()) {
|
||||
if (pat->GetTuple().elements->size() !=
|
||||
val->GetTuple().elements->size()) {
|
||||
std::cerr << "runtime error: arity mismatch in tuple pattern match"
|
||||
<< std::endl;
|
||||
exit(-1);
|
||||
}
|
||||
for (const TupleElement& element : *pat->u.tuple.elements) {
|
||||
for (const TupleElement& element : *pat->GetTuple().elements) {
|
||||
auto a = FindTupleField(element.name, val);
|
||||
if (a == std::nullopt) {
|
||||
std::cerr << "runtime error: field " << element.name << "not in ";
|
||||
@@ -557,14 +570,17 @@ void PatternAssignment(const Value* pat, const Value* val, int line_num) {
|
||||
case ValKind::AltV: {
|
||||
switch (val->tag) {
|
||||
case ValKind::AltV: {
|
||||
if (*pat->u.alt.choice_name != *val->u.alt.choice_name ||
|
||||
*pat->u.alt.alt_name != *val->u.alt.alt_name) {
|
||||
if (*pat->GetAlternative().choice_name !=
|
||||
*val->GetAlternative().choice_name ||
|
||||
*pat->GetAlternative().alt_name !=
|
||||
*val->GetAlternative().alt_name) {
|
||||
std::cerr << "internal error in pattern assignment" << std::endl;
|
||||
exit(-1);
|
||||
}
|
||||
PatternAssignment(state->heap.Read(pat->u.alt.argument, line_num),
|
||||
state->heap.Read(val->u.alt.argument, line_num),
|
||||
line_num);
|
||||
PatternAssignment(
|
||||
state->heap.Read(pat->GetAlternative().argument, line_num),
|
||||
state->heap.Read(val->GetAlternative().argument, line_num),
|
||||
line_num);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@@ -601,13 +617,13 @@ void StepLvalue() {
|
||||
// { {x :: C, E, F} :: S, H}
|
||||
// -> { {E(x) :: C, E, F} :: S, H}
|
||||
std::optional<Address> pointer =
|
||||
CurrentEnv(state).Get(*(exp->u.variable.name));
|
||||
CurrentEnv(state).Get(*(exp->GetVariable().name));
|
||||
if (!pointer) {
|
||||
std::cerr << exp->line_num << ": could not find `"
|
||||
<< *(exp->u.variable.name) << "`" << std::endl;
|
||||
<< *(exp->GetVariable().name) << "`" << std::endl;
|
||||
exit(-1);
|
||||
}
|
||||
const Value* v = MakePtrVal(*pointer);
|
||||
const Value* v = Value::MakePtrVal(*pointer);
|
||||
frame->todo.Pop();
|
||||
frame->todo.Push(MakeValAct(v));
|
||||
break;
|
||||
@@ -615,21 +631,21 @@ void StepLvalue() {
|
||||
case ExpressionKind::GetField: {
|
||||
// { {e.f :: C, E, F} :: S, H}
|
||||
// -> { e :: [].f :: C, E, F} :: S, H}
|
||||
frame->todo.Push(MakeLvalAct(exp->u.get_field.aggregate));
|
||||
frame->todo.Push(MakeLvalAct(exp->GetFieldAccess().aggregate));
|
||||
act->pos++;
|
||||
break;
|
||||
}
|
||||
case ExpressionKind::Index: {
|
||||
// { {e[i] :: C, E, F} :: S, H}
|
||||
// -> { e :: [][i] :: C, E, F} :: S, H}
|
||||
frame->todo.Push(MakeExpAct(exp->u.index.aggregate));
|
||||
frame->todo.Push(MakeExpAct(exp->GetIndex().aggregate));
|
||||
act->pos++;
|
||||
break;
|
||||
}
|
||||
case ExpressionKind::Tuple: {
|
||||
// { {(f1=e1,...) :: C, E, F} :: S, H}
|
||||
// -> { {e1 :: (f1=[],...) :: C, E, F} :: S, H}
|
||||
const Expression* e1 = (*exp->u.tuple.fields)[0].expression;
|
||||
const Expression* e1 = (*exp->GetTuple().fields)[0].expression;
|
||||
frame->todo.Push(MakeLvalAct(e1));
|
||||
act->pos++;
|
||||
break;
|
||||
@@ -665,22 +681,22 @@ void StepExp() {
|
||||
}
|
||||
switch (exp->tag) {
|
||||
case ExpressionKind::PatternVariable: {
|
||||
frame->todo.Push(MakeExpAct(exp->u.pattern_variable.type));
|
||||
frame->todo.Push(MakeExpAct(exp->GetPatternVariable().type));
|
||||
act->pos++;
|
||||
break;
|
||||
}
|
||||
case ExpressionKind::Index: {
|
||||
// { { e[i] :: C, E, F} :: S, H}
|
||||
// -> { { e :: [][i] :: C, E, F} :: S, H}
|
||||
frame->todo.Push(MakeExpAct(exp->u.index.aggregate));
|
||||
frame->todo.Push(MakeExpAct(exp->GetIndex().aggregate));
|
||||
act->pos++;
|
||||
break;
|
||||
}
|
||||
case ExpressionKind::Tuple: {
|
||||
if (exp->u.tuple.fields->size() > 0) {
|
||||
if (exp->GetTuple().fields->size() > 0) {
|
||||
// { {(f1=e1,...) :: C, E, F} :: S, H}
|
||||
// -> { {e1 :: (f1=[],...) :: C, E, F} :: S, H}
|
||||
const Expression* e1 = (*exp->u.tuple.fields)[0].expression;
|
||||
const Expression* e1 = (*exp->GetTuple().fields)[0].expression;
|
||||
frame->todo.Push(MakeExpAct(e1));
|
||||
act->pos++;
|
||||
} else {
|
||||
@@ -691,17 +707,17 @@ void StepExp() {
|
||||
case ExpressionKind::GetField: {
|
||||
// { { e.f :: C, E, F} :: S, H}
|
||||
// -> { { e :: [].f :: C, E, F} :: S, H}
|
||||
frame->todo.Push(MakeLvalAct(exp->u.get_field.aggregate));
|
||||
frame->todo.Push(MakeLvalAct(exp->GetFieldAccess().aggregate));
|
||||
act->pos++;
|
||||
break;
|
||||
}
|
||||
case ExpressionKind::Variable: {
|
||||
// { {x :: C, E, F} :: S, H} -> { {H(E(x)) :: C, E, F} :: S, H}
|
||||
std::optional<Address> pointer =
|
||||
CurrentEnv(state).Get(*(exp->u.variable.name));
|
||||
CurrentEnv(state).Get(*(exp->GetVariable().name));
|
||||
if (!pointer) {
|
||||
std::cerr << exp->line_num << ": could not find `"
|
||||
<< *(exp->u.variable.name) << "`" << std::endl;
|
||||
<< *(exp->GetVariable().name) << "`" << std::endl;
|
||||
exit(-1);
|
||||
}
|
||||
const Value* pointee = state->heap.Read(*pointer, exp->line_num);
|
||||
@@ -712,24 +728,25 @@ void StepExp() {
|
||||
case ExpressionKind::Integer:
|
||||
// { {n :: C, E, F} :: S, H} -> { {n' :: C, E, F} :: S, H}
|
||||
frame->todo.Pop(1);
|
||||
frame->todo.Push(MakeValAct(MakeIntVal(exp->u.integer)));
|
||||
frame->todo.Push(MakeValAct(Value::MakeIntVal(exp->GetInteger())));
|
||||
break;
|
||||
case ExpressionKind::Boolean:
|
||||
// { {n :: C, E, F} :: S, H} -> { {n' :: C, E, F} :: S, H}
|
||||
frame->todo.Pop(1);
|
||||
frame->todo.Push(MakeValAct(MakeBoolVal(exp->u.boolean)));
|
||||
frame->todo.Push(MakeValAct(Value::MakeBoolVal(exp->GetBoolean())));
|
||||
break;
|
||||
case ExpressionKind::PrimitiveOp:
|
||||
if (exp->u.primitive_op.arguments->size() > 0) {
|
||||
if (exp->GetPrimitiveOperator().arguments->size() > 0) {
|
||||
// { {op(e :: es) :: C, E, F} :: S, H}
|
||||
// -> { e :: op([] :: es) :: C, E, F} :: S, H}
|
||||
frame->todo.Push(MakeExpAct(exp->u.primitive_op.arguments->front()));
|
||||
frame->todo.Push(
|
||||
MakeExpAct(exp->GetPrimitiveOperator().arguments->front()));
|
||||
act->pos++;
|
||||
} else {
|
||||
// { {v :: op(]) :: C, E, F} :: S, H}
|
||||
// -> { {eval_prim(op, ()) :: C, E, F} :: S, H}
|
||||
const Value* v =
|
||||
EvalPrim(exp->u.primitive_op.op, act->results, exp->line_num);
|
||||
const Value* v = EvalPrim(exp->GetPrimitiveOperator().op, act->results,
|
||||
exp->line_num);
|
||||
frame->todo.Pop(2);
|
||||
frame->todo.Push(MakeValAct(v));
|
||||
}
|
||||
@@ -737,40 +754,40 @@ void StepExp() {
|
||||
case ExpressionKind::Call:
|
||||
// { {e1(e2) :: C, E, F} :: S, H}
|
||||
// -> { {e1 :: [](e2) :: C, E, F} :: S, H}
|
||||
frame->todo.Push(MakeExpAct(exp->u.call.function));
|
||||
frame->todo.Push(MakeExpAct(exp->GetCall().function));
|
||||
act->pos++;
|
||||
break;
|
||||
case ExpressionKind::IntT: {
|
||||
const Value* v = MakeIntTypeVal();
|
||||
const Value* v = Value::MakeIntTypeVal();
|
||||
frame->todo.Pop(1);
|
||||
frame->todo.Push(MakeValAct(v));
|
||||
break;
|
||||
}
|
||||
case ExpressionKind::BoolT: {
|
||||
const Value* v = MakeBoolTypeVal();
|
||||
const Value* v = Value::MakeBoolTypeVal();
|
||||
frame->todo.Pop(1);
|
||||
frame->todo.Push(MakeValAct(v));
|
||||
break;
|
||||
}
|
||||
case ExpressionKind::AutoT: {
|
||||
const Value* v = MakeAutoTypeVal();
|
||||
const Value* v = Value::MakeAutoTypeVal();
|
||||
frame->todo.Pop(1);
|
||||
frame->todo.Push(MakeValAct(v));
|
||||
break;
|
||||
}
|
||||
case ExpressionKind::TypeT: {
|
||||
const Value* v = MakeTypeTypeVal();
|
||||
const Value* v = Value::MakeTypeTypeVal();
|
||||
frame->todo.Pop(1);
|
||||
frame->todo.Push(MakeValAct(v));
|
||||
break;
|
||||
}
|
||||
case ExpressionKind::FunctionT: {
|
||||
frame->todo.Push(MakeExpAct(exp->u.function_type.parameter));
|
||||
frame->todo.Push(MakeExpAct(exp->GetFunctionType().parameter));
|
||||
act->pos++;
|
||||
break;
|
||||
}
|
||||
case ExpressionKind::ContinuationT: {
|
||||
const Value* v = MakeContinuationTypeVal();
|
||||
const Value* v = Value::MakeContinuationTypeVal();
|
||||
frame->todo.Pop(1);
|
||||
frame->todo.Push(MakeValAct(v));
|
||||
break;
|
||||
@@ -822,13 +839,13 @@ void StepStmt() {
|
||||
case StatementKind::Match:
|
||||
// { { (match (e) ...) :: C, E, F} :: S, H}
|
||||
// -> { { e :: (match ([]) ...) :: C, E, F} :: S, H}
|
||||
frame->todo.Push(MakeExpAct(stmt->u.match_stmt.exp));
|
||||
frame->todo.Push(MakeExpAct(stmt->GetMatch().exp));
|
||||
act->pos++;
|
||||
break;
|
||||
case StatementKind::While:
|
||||
// { { (while (e) s) :: C, E, F} :: S, H}
|
||||
// -> { { e :: (while ([]) s) :: C, E, F} :: S, H}
|
||||
frame->todo.Push(MakeExpAct(stmt->u.while_stmt.cond));
|
||||
frame->todo.Push(MakeExpAct(stmt->GetWhile().cond));
|
||||
act->pos++;
|
||||
break;
|
||||
case StatementKind::Break:
|
||||
@@ -858,10 +875,10 @@ void StepStmt() {
|
||||
break;
|
||||
case StatementKind::Block: {
|
||||
if (act->pos == -1) {
|
||||
if (stmt->u.block.stmt) {
|
||||
if (stmt->GetBlock().stmt) {
|
||||
auto* scope = new Scope(CurrentEnv(state), {});
|
||||
frame->scopes.Push(scope);
|
||||
frame->todo.Push(MakeStmtAct(stmt->u.block.stmt));
|
||||
frame->todo.Push(MakeStmtAct(stmt->GetBlock().stmt));
|
||||
act->pos++;
|
||||
} else {
|
||||
frame->todo.Pop();
|
||||
@@ -877,40 +894,40 @@ void StepStmt() {
|
||||
case StatementKind::VariableDefinition:
|
||||
// { {(var x = e) :: C, E, F} :: S, H}
|
||||
// -> { {e :: (var x = []) :: C, E, F} :: S, H}
|
||||
frame->todo.Push(MakeExpAct(stmt->u.variable_definition.init));
|
||||
frame->todo.Push(MakeExpAct(stmt->GetVariableDefinition().init));
|
||||
act->pos++;
|
||||
break;
|
||||
case StatementKind::ExpressionStatement:
|
||||
// { {e :: C, E, F} :: S, H}
|
||||
// -> { {e :: C, E, F} :: S, H}
|
||||
frame->todo.Push(MakeExpAct(stmt->u.exp));
|
||||
frame->todo.Push(MakeExpAct(stmt->GetExpression()));
|
||||
break;
|
||||
case StatementKind::Assign:
|
||||
// { {(lv = e) :: C, E, F} :: S, H}
|
||||
// -> { {lv :: ([] = e) :: C, E, F} :: S, H}
|
||||
frame->todo.Push(MakeLvalAct(stmt->u.assign.lhs));
|
||||
frame->todo.Push(MakeLvalAct(stmt->GetAssign().lhs));
|
||||
act->pos++;
|
||||
break;
|
||||
case StatementKind::If:
|
||||
// { {(if (e) then_stmt else else_stmt) :: C, E, F} :: S, H}
|
||||
// -> { { e :: (if ([]) then_stmt else else_stmt) :: C, E, F} :: S, H}
|
||||
frame->todo.Push(MakeExpAct(stmt->u.if_stmt.cond));
|
||||
frame->todo.Push(MakeExpAct(stmt->GetIf().cond));
|
||||
act->pos++;
|
||||
break;
|
||||
case StatementKind::Return:
|
||||
// { {return e :: C, E, F} :: S, H}
|
||||
// -> { {e :: return [] :: C, E, F} :: S, H}
|
||||
frame->todo.Push(MakeExpAct(stmt->u.return_stmt));
|
||||
frame->todo.Push(MakeExpAct(stmt->GetReturn()));
|
||||
act->pos++;
|
||||
break;
|
||||
case StatementKind::Sequence:
|
||||
// { { (s1,s2) :: C, E, F} :: S, H}
|
||||
// -> { { s1 :: s2 :: C, E, F} :: S, H}
|
||||
frame->todo.Pop(1);
|
||||
if (stmt->u.sequence.next) {
|
||||
frame->todo.Push(MakeStmtAct(stmt->u.sequence.next));
|
||||
if (stmt->GetSequence().next) {
|
||||
frame->todo.Push(MakeStmtAct(stmt->GetSequence().next));
|
||||
}
|
||||
frame->todo.Push(MakeStmtAct(stmt->u.sequence.stmt));
|
||||
frame->todo.Push(MakeStmtAct(stmt->GetSequence().stmt));
|
||||
break;
|
||||
case StatementKind::Continuation: {
|
||||
// Create a continuation object by creating a frame similar the
|
||||
@@ -919,24 +936,24 @@ void StepStmt() {
|
||||
Stack<Scope*> scopes;
|
||||
scopes.Push(scope);
|
||||
Stack<Action*> todo;
|
||||
todo.Push(
|
||||
MakeStmtAct(MakeReturn(stmt->line_num, MakeUnit(stmt->line_num))));
|
||||
todo.Push(MakeStmtAct(stmt->u.continuation.body));
|
||||
todo.Push(MakeStmtAct(Statement::MakeReturn(
|
||||
stmt->line_num, Expression::MakeUnit(stmt->line_num))));
|
||||
todo.Push(MakeStmtAct(stmt->GetContinuation().body));
|
||||
Frame* continuation_frame = new Frame("__continuation", scopes, todo);
|
||||
Address continuation_address =
|
||||
state->heap.AllocateValue(MakeContinuation({continuation_frame}));
|
||||
Address continuation_address = state->heap.AllocateValue(
|
||||
Value::MakeContinuation({continuation_frame}));
|
||||
// Store the continuation's address in the frame.
|
||||
continuation_frame->continuation = continuation_address;
|
||||
// Bind the continuation object to the continuation variable
|
||||
frame->scopes.Top()->values.Set(
|
||||
*stmt->u.continuation.continuation_variable, continuation_address);
|
||||
*stmt->GetContinuation().continuation_variable, continuation_address);
|
||||
// Pop the continuation statement.
|
||||
frame->todo.Pop();
|
||||
break;
|
||||
}
|
||||
case StatementKind::Run:
|
||||
// Evaluate the argument of the run statement.
|
||||
frame->todo.Push(MakeExpAct(stmt->u.run.argument));
|
||||
frame->todo.Push(MakeExpAct(stmt->GetRun().argument));
|
||||
act->pos++;
|
||||
break;
|
||||
case StatementKind::Await:
|
||||
@@ -947,8 +964,8 @@ void StepStmt() {
|
||||
paused.push_back(state->stack.Pop());
|
||||
} while (!paused.back()->IsContinuation());
|
||||
// Update the continuation with the paused stack.
|
||||
state->heap.Write(paused.back()->continuation, MakeContinuation(paused),
|
||||
stmt->line_num);
|
||||
state->heap.Write(paused.back()->continuation,
|
||||
Value::MakeContinuation(paused), stmt->line_num);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -957,7 +974,7 @@ auto GetMember(Address a, const std::string& f, int line_num) -> Address {
|
||||
const Value* v = state->heap.Read(a, line_num);
|
||||
switch (v->tag) {
|
||||
case ValKind::StructV: {
|
||||
auto a = FindTupleField(f, v->u.struct_val.inits);
|
||||
auto a = FindTupleField(f, v->GetStruct().inits);
|
||||
if (a == std::nullopt) {
|
||||
std::cerr << "runtime error, member " << f << " not in ";
|
||||
PrintValue(v, std::cerr);
|
||||
@@ -977,13 +994,13 @@ auto GetMember(Address a, const std::string& f, int line_num) -> Address {
|
||||
return *a;
|
||||
}
|
||||
case ValKind::ChoiceTV: {
|
||||
if (FindInVarValues(f, v->u.choice_type.alternatives) == nullptr) {
|
||||
if (FindInVarValues(f, v->GetChoiceType().alternatives) == nullptr) {
|
||||
std::cerr << "alternative " << f << " not in ";
|
||||
PrintValue(v, std::cerr);
|
||||
std::cerr << std::endl;
|
||||
exit(-1);
|
||||
}
|
||||
auto ac = MakeAltCons(f, *v->u.choice_type.name);
|
||||
auto ac = Value::MakeAltCons(f, *v->GetChoiceType().name);
|
||||
return state->heap.AllocateValue(ac);
|
||||
}
|
||||
default:
|
||||
@@ -1047,7 +1064,7 @@ void HandleValue() {
|
||||
auto del = MakeDeleteAct(a);
|
||||
frame->todo.Pop(2);
|
||||
InsertDelete(del, frame->todo);
|
||||
frame->todo.Push(MakeValAct(MakePtrVal(a)));
|
||||
frame->todo.Push(MakeValAct(Value::MakePtrVal(a)));
|
||||
break;
|
||||
}
|
||||
case ActionKind::LValAction: {
|
||||
@@ -1058,15 +1075,15 @@ void HandleValue() {
|
||||
// -> { { &v.f :: C, E, F} :: S, H }
|
||||
const Value* str = act->results[0];
|
||||
Address a = GetMember(ValToPtr(str, exp->line_num),
|
||||
*exp->u.get_field.field, exp->line_num);
|
||||
*exp->GetFieldAccess().field, exp->line_num);
|
||||
frame->todo.Pop(2);
|
||||
frame->todo.Push(MakeValAct(MakePtrVal(a)));
|
||||
frame->todo.Push(MakeValAct(Value::MakePtrVal(a)));
|
||||
break;
|
||||
}
|
||||
case ExpressionKind::Index: {
|
||||
if (act->pos == 1) {
|
||||
frame->todo.Pop(1);
|
||||
frame->todo.Push(MakeExpAct(exp->u.index.offset));
|
||||
frame->todo.Push(MakeExpAct(exp->GetIndex().offset));
|
||||
} else if (act->pos == 2) {
|
||||
// { v :: [][i] :: C, E, F} :: S, H}
|
||||
// -> { { &v[i] :: C, E, F} :: S, H }
|
||||
@@ -1080,17 +1097,18 @@ void HandleValue() {
|
||||
exit(-1);
|
||||
}
|
||||
frame->todo.Pop(2);
|
||||
frame->todo.Push(MakeValAct(MakePtrVal(*a)));
|
||||
frame->todo.Push(MakeValAct(Value::MakePtrVal(*a)));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ExpressionKind::Tuple: {
|
||||
if (act->pos != static_cast<int>(exp->u.tuple.fields->size())) {
|
||||
if (act->pos != static_cast<int>(exp->GetTuple().fields->size())) {
|
||||
// { { vk :: (f1=v1,..., fk=[],fk+1=ek+1,...) :: C, E, F} :: S,
|
||||
// H}
|
||||
// -> { { ek+1 :: (f1=v1,..., fk=vk, fk+1=[],...) :: C, E, F} :: S,
|
||||
// H}
|
||||
const Expression* elt = (*exp->u.tuple.fields)[act->pos].expression;
|
||||
const Expression* elt =
|
||||
(*exp->GetTuple().fields)[act->pos].expression;
|
||||
frame->todo.Pop(1);
|
||||
frame->todo.Push(MakeLvalAct(elt));
|
||||
} else {
|
||||
@@ -1110,19 +1128,20 @@ void HandleValue() {
|
||||
const Expression* exp = act->u.exp;
|
||||
switch (exp->tag) {
|
||||
case ExpressionKind::PatternVariable: {
|
||||
auto v =
|
||||
MakeVarPatVal(*exp->u.pattern_variable.name, act->results[0]);
|
||||
auto v = Value::MakeVarPatVal(*exp->GetPatternVariable().name,
|
||||
act->results[0]);
|
||||
frame->todo.Pop(2);
|
||||
frame->todo.Push(MakeValAct(v));
|
||||
break;
|
||||
}
|
||||
case ExpressionKind::Tuple: {
|
||||
if (act->pos != static_cast<int>(exp->u.tuple.fields->size())) {
|
||||
if (act->pos != static_cast<int>(exp->GetTuple().fields->size())) {
|
||||
// { { vk :: (f1=v1,..., fk=[],fk+1=ek+1,...) :: C, E, F} :: S,
|
||||
// H}
|
||||
// -> { { ek+1 :: (f1=v1,..., fk=vk, fk+1=[],...) :: C, E, F} :: S,
|
||||
// H}
|
||||
const Expression* elt = (*exp->u.tuple.fields)[act->pos].expression;
|
||||
const Expression* elt =
|
||||
(*exp->GetTuple().fields)[act->pos].expression;
|
||||
frame->todo.Pop(1);
|
||||
frame->todo.Push(MakeExpAct(elt));
|
||||
} else {
|
||||
@@ -1134,7 +1153,7 @@ void HandleValue() {
|
||||
case ExpressionKind::Index: {
|
||||
if (act->pos == 1) {
|
||||
frame->todo.Pop(1);
|
||||
frame->todo.Push(MakeExpAct(exp->u.index.offset));
|
||||
frame->todo.Push(MakeExpAct(exp->GetIndex().offset));
|
||||
} else if (act->pos == 2) {
|
||||
auto tuple = act->results[0];
|
||||
switch (tuple->tag) {
|
||||
@@ -1168,7 +1187,7 @@ void HandleValue() {
|
||||
// { { v :: [].f :: C, E, F} :: S, H}
|
||||
// -> { { v_f :: C, E, F} : S, H}
|
||||
auto a = GetMember(ValToPtr(act->results[0], exp->line_num),
|
||||
*exp->u.get_field.field, exp->line_num);
|
||||
*exp->GetFieldAccess().field, exp->line_num);
|
||||
const Value* element = state->heap.Read(a, exp->line_num);
|
||||
frame->todo.Pop(2);
|
||||
frame->todo.Push(MakeValAct(element));
|
||||
@@ -1176,17 +1195,18 @@ void HandleValue() {
|
||||
}
|
||||
case ExpressionKind::PrimitiveOp: {
|
||||
if (act->pos !=
|
||||
static_cast<int>(exp->u.primitive_op.arguments->size())) {
|
||||
static_cast<int>(exp->GetPrimitiveOperator().arguments->size())) {
|
||||
// { {v :: op(vs,[],e,es) :: C, E, F} :: S, H}
|
||||
// -> { {e :: op(vs,v,[],es) :: C, E, F} :: S, H}
|
||||
const Expression* arg = (*exp->u.primitive_op.arguments)[act->pos];
|
||||
const Expression* arg =
|
||||
(*exp->GetPrimitiveOperator().arguments)[act->pos];
|
||||
frame->todo.Pop(1);
|
||||
frame->todo.Push(MakeExpAct(arg));
|
||||
} else {
|
||||
// { {v :: op(vs,[]) :: C, E, F} :: S, H}
|
||||
// -> { {eval_prim(op, (vs,v)) :: C, E, F} :: S, H}
|
||||
const Value* v =
|
||||
EvalPrim(exp->u.primitive_op.op, act->results, exp->line_num);
|
||||
const Value* v = EvalPrim(exp->GetPrimitiveOperator().op,
|
||||
act->results, exp->line_num);
|
||||
frame->todo.Pop(2);
|
||||
frame->todo.Push(MakeValAct(v));
|
||||
}
|
||||
@@ -1197,7 +1217,7 @@ void HandleValue() {
|
||||
// { { v :: [](e) :: C, E, F} :: S, H}
|
||||
// -> { { e :: v([]) :: C, E, F} :: S, H}
|
||||
frame->todo.Pop(1);
|
||||
frame->todo.Push(MakeExpAct(exp->u.call.argument));
|
||||
frame->todo.Push(MakeExpAct(exp->GetCall().argument));
|
||||
} else if (act->pos == 2) {
|
||||
// { { v2 :: v1([]) :: C, E, F} :: S, H}
|
||||
// -> { {C',E',F'} :: {C, E, F} :: S, H}
|
||||
@@ -1214,14 +1234,15 @@ void HandleValue() {
|
||||
if (act->pos == 2) {
|
||||
// { { rt :: fn pt -> [] :: C, E, F} :: S, H}
|
||||
// -> { fn pt -> rt :: {C, E, F} :: S, H}
|
||||
const Value* v = MakeFunTypeVal(act->results[0], act->results[1]);
|
||||
const Value* v =
|
||||
Value::MakeFunTypeVal(act->results[0], act->results[1]);
|
||||
frame->todo.Pop(2);
|
||||
frame->todo.Push(MakeValAct(v));
|
||||
} else {
|
||||
// { { pt :: fn [] -> e :: C, E, F} :: S, H}
|
||||
// -> { { e :: fn pt -> []) :: C, E, F} :: S, H}
|
||||
frame->todo.Pop(1);
|
||||
frame->todo.Push(MakeExpAct(exp->u.function_type.return_type));
|
||||
frame->todo.Push(MakeExpAct(exp->GetFunctionType().return_type));
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -1248,7 +1269,7 @@ void HandleValue() {
|
||||
case StatementKind::VariableDefinition: {
|
||||
if (act->pos == 1) {
|
||||
frame->todo.Pop(1);
|
||||
frame->todo.Push(MakeExpAct(stmt->u.variable_definition.pat));
|
||||
frame->todo.Push(MakeExpAct(stmt->GetVariableDefinition().pat));
|
||||
} else if (act->pos == 2) {
|
||||
// { { v :: (x = []) :: C, E, F} :: S, H}
|
||||
// -> { { C, E(x := a), F} :: S, H(a := copy(v))}
|
||||
@@ -1275,7 +1296,7 @@ void HandleValue() {
|
||||
// { { a :: ([] = e) :: C, E, F} :: S, H}
|
||||
// -> { { e :: (a = []) :: C, E, F} :: S, H}
|
||||
frame->todo.Pop(1);
|
||||
frame->todo.Push(MakeExpAct(stmt->u.assign.rhs));
|
||||
frame->todo.Push(MakeExpAct(stmt->GetAssign().rhs));
|
||||
} else if (act->pos == 2) {
|
||||
// { { v :: (a = []) :: C, E, F} :: S, H}
|
||||
// -> { { C, E, F} :: S, H(a := v)}
|
||||
@@ -1291,13 +1312,13 @@ void HandleValue() {
|
||||
// S, H}
|
||||
// -> { { 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) {
|
||||
frame->todo.Push(MakeStmtAct(stmt->GetIf().then_stmt));
|
||||
} else if (stmt->GetIf().else_stmt) {
|
||||
// { {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));
|
||||
frame->todo.Push(MakeStmtAct(stmt->GetIf().else_stmt));
|
||||
} else {
|
||||
frame->todo.Pop(2);
|
||||
}
|
||||
@@ -1309,7 +1330,7 @@ void HandleValue() {
|
||||
frame->todo.Pop(1);
|
||||
frame->todo.Top()->pos = -1;
|
||||
frame->todo.Top()->results.clear();
|
||||
frame->todo.Push(MakeStmtAct(stmt->u.while_stmt.body));
|
||||
frame->todo.Push(MakeStmtAct(stmt->GetWhile().body));
|
||||
} else {
|
||||
// { {false :: (while ([]) s) :: C, E, F} :: S, H}
|
||||
// -> { { C, E, F } :: S, H}
|
||||
@@ -1331,11 +1352,11 @@ void HandleValue() {
|
||||
// * ...
|
||||
auto clause_num = (act->pos - 1) / 2;
|
||||
if (clause_num >=
|
||||
static_cast<int>(stmt->u.match_stmt.clauses->size())) {
|
||||
static_cast<int>(stmt->GetMatch().clauses->size())) {
|
||||
frame->todo.Pop(2);
|
||||
break;
|
||||
}
|
||||
auto c = stmt->u.match_stmt.clauses->begin();
|
||||
auto c = stmt->GetMatch().clauses->begin();
|
||||
std::advance(c, clause_num);
|
||||
|
||||
if (act->pos % 2 == 1) {
|
||||
@@ -1355,7 +1376,7 @@ void HandleValue() {
|
||||
auto* new_scope = new Scope(*matches, vars);
|
||||
frame->scopes.Push(new_scope);
|
||||
const Statement* body_block =
|
||||
MakeBlock(stmt->line_num, c->second);
|
||||
Statement::MakeBlock(stmt->line_num, c->second);
|
||||
Action* body_act = MakeStmtAct(body_block);
|
||||
body_act->pos = 0;
|
||||
frame->todo.Pop(2);
|
||||
@@ -1366,9 +1387,9 @@ void HandleValue() {
|
||||
act->pos++;
|
||||
clause_num = (act->pos - 1) / 2;
|
||||
if (clause_num <
|
||||
static_cast<int>(stmt->u.match_stmt.clauses->size())) {
|
||||
static_cast<int>(stmt->GetMatch().clauses->size())) {
|
||||
// interpret the next clause
|
||||
c = stmt->u.match_stmt.clauses->begin();
|
||||
c = stmt->GetMatch().clauses->begin();
|
||||
std::advance(c, clause_num);
|
||||
frame->todo.Pop(1);
|
||||
frame->todo.Push(MakeExpAct(c->first));
|
||||
@@ -1393,8 +1414,8 @@ void HandleValue() {
|
||||
frame->todo.Pop(2);
|
||||
// Push an expression statement action to ignore the result
|
||||
// value from the continuation.
|
||||
Action* ignore_result = MakeStmtAct(
|
||||
MakeExpStmt(stmt->line_num, MakeUnit(stmt->line_num)));
|
||||
Action* ignore_result = MakeStmtAct(Statement::MakeExpStmt(
|
||||
stmt->line_num, Expression::MakeUnit(stmt->line_num)));
|
||||
ignore_result->pos = 0;
|
||||
frame->todo.Push(ignore_result);
|
||||
// Push the continuation onto the current stack.
|
||||
@@ -1467,8 +1488,10 @@ auto InterpProgram(std::list<Declaration>* fs) -> int {
|
||||
}
|
||||
InitGlobals(fs);
|
||||
|
||||
const Expression* arg = MakeTuple(0, new std::vector<FieldInitializer>());
|
||||
const Expression* call_main = MakeCall(0, MakeVar(0, "main"), arg);
|
||||
const Expression* arg =
|
||||
Expression::MakeTuple(0, new std::vector<FieldInitializer>());
|
||||
const Expression* call_main =
|
||||
Expression::MakeCall(0, Expression::MakeVar(0, "main"), arg);
|
||||
auto todo = Stack(MakeExpAct(call_main));
|
||||
auto* scope = new Scope(globals, std::list<std::string>());
|
||||
auto* frame = new Frame("top", Stack(scope), todo);
|
||||
|
||||
Reference in New Issue
Block a user