|
|
@@ -60,6 +60,15 @@ auto CurrentEnv(State* state) -> Env {
|
|
|
return frame->scopes.Top()->values;
|
|
|
}
|
|
|
|
|
|
+// Returns the given name from the environment, printing an error if not found.
|
|
|
+static auto GetFromEnv(int line_num, const std::string& name) -> Address {
|
|
|
+ std::optional<Address> pointer = CurrentEnv(state).Get(name);
|
|
|
+ if (!pointer) {
|
|
|
+ FATAL_RUNTIME_ERROR(line_num) << "could not find `" << name << "`";
|
|
|
+ }
|
|
|
+ return *pointer;
|
|
|
+}
|
|
|
+
|
|
|
void PrintState(llvm::raw_ostream& out) {
|
|
|
out << "{\nstack: ";
|
|
|
PrintStack(state->stack, out);
|
|
|
@@ -411,14 +420,9 @@ void StepLvalue() {
|
|
|
case Expression::Kind::IdentifierExpression: {
|
|
|
// { {x :: C, E, F} :: S, H}
|
|
|
// -> { {E(x) :: C, E, F} :: S, H}
|
|
|
- std::optional<Address> pointer =
|
|
|
- CurrentEnv(state).Get(cast<IdentifierExpression>(*exp).Name());
|
|
|
- if (!pointer) {
|
|
|
- FATAL_RUNTIME_ERROR(exp->LineNumber())
|
|
|
- << "could not find `" << cast<IdentifierExpression>(*exp).Name()
|
|
|
- << "`";
|
|
|
- }
|
|
|
- const Value* v = global_arena->New<PointerValue>(*pointer);
|
|
|
+ Address pointer = GetFromEnv(exp->LineNumber(),
|
|
|
+ cast<IdentifierExpression>(*exp).Name());
|
|
|
+ const Value* v = global_arena->New<PointerValue>(pointer);
|
|
|
frame->todo.Pop();
|
|
|
frame->todo.Push(global_arena->New<ValAction>(v));
|
|
|
break;
|
|
|
@@ -496,10 +500,12 @@ void StepLvalue() {
|
|
|
case Expression::Kind::BoolTypeLiteral:
|
|
|
case Expression::Kind::TypeTypeLiteral:
|
|
|
case Expression::Kind::FunctionTypeLiteral:
|
|
|
- case Expression::Kind::ContinuationTypeLiteral: {
|
|
|
+ case Expression::Kind::ContinuationTypeLiteral:
|
|
|
+ case Expression::Kind::StringLiteral:
|
|
|
+ case Expression::Kind::StringTypeLiteral:
|
|
|
+ case Expression::Kind::IntrinsicExpression:
|
|
|
FATAL_RUNTIME_ERROR_NO_LINE()
|
|
|
<< "Can't treat expression as lvalue: " << *exp;
|
|
|
- }
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -597,12 +603,8 @@ void StepExp() {
|
|
|
CHECK(act->Pos() == 0);
|
|
|
const auto& ident = cast<IdentifierExpression>(*exp);
|
|
|
// { {x :: C, E, F} :: S, H} -> { {H(E(x)) :: C, E, F} :: S, H}
|
|
|
- std::optional<Address> pointer = CurrentEnv(state).Get(ident.Name());
|
|
|
- if (!pointer) {
|
|
|
- FATAL_RUNTIME_ERROR(exp->LineNumber())
|
|
|
- << "could not find `" << ident.Name() << "`";
|
|
|
- }
|
|
|
- const Value* pointee = state->heap.Read(*pointer, exp->LineNumber());
|
|
|
+ Address pointer = GetFromEnv(exp->LineNumber(), ident.Name());
|
|
|
+ const Value* pointee = state->heap.Read(pointer, exp->LineNumber());
|
|
|
frame->todo.Pop(1);
|
|
|
frame->todo.Push(global_arena->New<ValAction>(pointee));
|
|
|
break;
|
|
|
@@ -660,6 +662,22 @@ void StepExp() {
|
|
|
FATAL() << "in handle_value with Call pos " << act->Pos();
|
|
|
}
|
|
|
break;
|
|
|
+ case Expression::Kind::IntrinsicExpression:
|
|
|
+ CHECK(act->Pos() == 0);
|
|
|
+ // { {n :: C, E, F} :: S, H} -> { {n' :: C, E, F} :: S, H}
|
|
|
+ frame->todo.Pop(1);
|
|
|
+ switch (cast<IntrinsicExpression>(*exp).Intrinsic()) {
|
|
|
+ case IntrinsicExpression::IntrinsicKind::Print:
|
|
|
+ Address pointer = GetFromEnv(exp->LineNumber(), "format_str");
|
|
|
+ const Value* pointee = state->heap.Read(pointer, exp->LineNumber());
|
|
|
+ CHECK(pointee->Tag() == Value::Kind::StringValue);
|
|
|
+ // TODO: This could eventually use something like llvm::formatv.
|
|
|
+ llvm::outs() << cast<StringValue>(*pointee).Val();
|
|
|
+ frame->todo.Push(global_arena->New<ValAction>(&TupleValue::Empty()));
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ break;
|
|
|
+
|
|
|
case Expression::Kind::IntTypeLiteral: {
|
|
|
CHECK(act->Pos() == 0);
|
|
|
const Value* v = global_arena->New<IntType>();
|
|
|
@@ -710,6 +728,20 @@ void StepExp() {
|
|
|
frame->todo.Push(global_arena->New<ValAction>(v));
|
|
|
break;
|
|
|
}
|
|
|
+ case Expression::Kind::StringLiteral:
|
|
|
+ CHECK(act->Pos() == 0);
|
|
|
+ // { {n :: C, E, F} :: S, H} -> { {n' :: C, E, F} :: S, H}
|
|
|
+ frame->todo.Pop(1);
|
|
|
+ frame->todo.Push(global_arena->New<ValAction>(
|
|
|
+ global_arena->New<StringValue>(cast<StringLiteral>(*exp).Val())));
|
|
|
+ break;
|
|
|
+ case Expression::Kind::StringTypeLiteral: {
|
|
|
+ CHECK(act->Pos() == 0);
|
|
|
+ const Value* v = global_arena->New<StringType>();
|
|
|
+ frame->todo.Pop(1);
|
|
|
+ frame->todo.Push(global_arena->New<ValAction>(v));
|
|
|
+ break;
|
|
|
+ }
|
|
|
} // switch (exp->Tag)
|
|
|
}
|
|
|
|