Implement the first IO function "print" to work via continuations
This commit is contained in:
parent
d496a95b51
commit
cf9aa08aea
3 changed files with 58 additions and 5 deletions
|
@ -23,6 +23,7 @@ enum class ErrorCode {
|
||||||
SyntaxError,
|
SyntaxError,
|
||||||
RuntimeError,
|
RuntimeError,
|
||||||
Raise,
|
Raise,
|
||||||
|
TaskFailed,
|
||||||
};
|
};
|
||||||
|
|
||||||
class Value;
|
class Value;
|
||||||
|
|
|
@ -307,8 +307,18 @@ Result<StackFrame> stdlib_raise(const StackFrame& stack) {
|
||||||
auto stack_size = TRY(stack.size());
|
auto stack_size = TRY(stack.size());
|
||||||
|
|
||||||
if (stack_size > 1) {
|
if (stack_size > 1) {
|
||||||
auto accumulator = TRY(stack.get(0));
|
auto result = TRY(stack.get(1));
|
||||||
auto res = TRY(stack.set(0, accumulator));
|
if (!result.is<TaskResult>()) return ERROR(TypeMismatch);
|
||||||
|
|
||||||
|
const auto& task_result = *result.to<TaskResult>();
|
||||||
|
|
||||||
|
auto error = TRY(task_result.error());
|
||||||
|
|
||||||
|
if (!error.is<Nil>()) {
|
||||||
|
return ERROR_OBJ(TaskFailed, error);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto res = TRY(stack.set(0, TRY(task_result.result())));
|
||||||
res = TRY(res.ret(0));
|
res = TRY(res.ret(0));
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
|
@ -376,7 +386,22 @@ Result<Value> stdlib_task_unknown(const Array& params) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Result<Value> stdlib_task_print(const Array& params) {
|
Result<Value> stdlib_task_print(const Array& params) {
|
||||||
return ERROR(NotImplemented);
|
auto size = TRY(params.size());
|
||||||
|
|
||||||
|
if (size != 1) {
|
||||||
|
auto err = Value(TRY(Error::create("argument-count-mismatch", "Argument count mismatch")));
|
||||||
|
return ERROR_OBJ(ArgumentCountMismatch, err);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto obj = TRY(params.get(0));
|
||||||
|
|
||||||
|
if (!obj.is<String>()) {
|
||||||
|
auto err = Value(TRY(Error::create("type-mismatch", "Type mismatch")));
|
||||||
|
return ERROR_OBJ(TypeMismatch, err);
|
||||||
|
}
|
||||||
|
|
||||||
|
print_string(*obj.to<String>());
|
||||||
|
return Value(TRY(Nil::create()));
|
||||||
}
|
}
|
||||||
|
|
||||||
#define STDLIB_TASK(name, id) \
|
#define STDLIB_TASK(name, id) \
|
||||||
|
|
31
src/vm.cpp
31
src/vm.cpp
|
@ -284,12 +284,39 @@ Result<StackFrame> VM::handle_raise(const Continuation& cont) {
|
||||||
// TODO: this should do proper stack unwinding
|
// TODO: this should do proper stack unwinding
|
||||||
auto value = TRY(cont.value());
|
auto value = TRY(cont.value());
|
||||||
|
|
||||||
std::cout << "Handle raise\n";
|
|
||||||
|
|
||||||
if (value.is<Error>()) {
|
if (value.is<Error>()) {
|
||||||
auto obj = TRY(cont.copy_value());
|
auto obj = TRY(cont.copy_value());
|
||||||
return ERROR_OBJ(Raise, obj);
|
return ERROR_OBJ(Raise, obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Value tr;
|
||||||
|
|
||||||
|
if (value.is<Task>()) {
|
||||||
|
auto task_id = value.to<Task>()->task_id();
|
||||||
|
auto params = TRY(value.to<Task>()->params());
|
||||||
|
|
||||||
|
auto res = call_stdlib_task((StdlibTaskId)task_id, params);
|
||||||
|
|
||||||
|
if (res.has_error()) {
|
||||||
|
const auto& err = geterrobj();
|
||||||
|
Value errobj;
|
||||||
|
if (err.is<Nil>()) {
|
||||||
|
errobj = Value(TRY(Error::create("unknown-error", "Unknown error")));
|
||||||
|
} else {
|
||||||
|
errobj = TRY(err.copy());
|
||||||
|
}
|
||||||
|
|
||||||
|
tr = Value(TRY(TaskResult::create(TRY(Nil::create()), errobj)));
|
||||||
|
} else {
|
||||||
|
tr = Value(
|
||||||
|
TRY(TaskResult::create(res.release_value(), TRY(Nil::create()))));
|
||||||
|
}
|
||||||
|
|
||||||
|
auto frame = TRY(cont.frame());
|
||||||
|
|
||||||
|
auto new_frame = frame.set(TRY(frame.size()), tr);
|
||||||
|
return new_frame;
|
||||||
|
}
|
||||||
return ERROR(TypeMismatch);
|
return ERROR(TypeMismatch);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue