Port print and println to use tasks/continuations
This commit is contained in:
parent
cf9aa08aea
commit
52eae6b3e3
2 changed files with 70 additions and 36 deletions
105
src/stdlib.cpp
105
src/stdlib.cpp
|
@ -22,14 +22,48 @@ struct StdlibTaskEntry {
|
|||
StdlibTaskIdPtr task_ptr;
|
||||
};
|
||||
|
||||
Result<StackFrame> raise_task(const StackFrame& stack, StdlibTaskId task_id,
|
||||
const Array& params) {
|
||||
auto val = Value(TRY(Task::create((uint64_t)task_id, params)));
|
||||
auto cont = Value(TRY(Continuation::create(val, stack)));
|
||||
|
||||
return ERROR_OBJ(Raise, cont);
|
||||
}
|
||||
|
||||
Result<StackFrame> raise_task(const StackFrame& stack, StdlibTaskId task_id,
|
||||
const Value& param) {
|
||||
Array params = TRY(Array::create());
|
||||
params = TRY(params.append(param));
|
||||
auto val = Value(TRY(Task::create((uint64_t)task_id, params)));
|
||||
auto cont = Value(TRY(Continuation::create(val, stack)));
|
||||
|
||||
return ERROR_OBJ(Raise, cont);
|
||||
}
|
||||
|
||||
Result<StackFrame> task_return(const StackFrame& stack, uint64_t idx) {
|
||||
auto result = TRY(stack.get(idx));
|
||||
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));
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
Result<StackFrame> stdlib_unknown(const StackFrame& stack) {
|
||||
return ERROR(NotImplemented);
|
||||
}
|
||||
|
||||
Result<StackFrame> stdlib_print(const StackFrame& stack) {
|
||||
auto params = TRY(stack.get(0));
|
||||
Result<String> tostring(const Value& params, bool newline = false) {
|
||||
auto size = TRY(params.size());
|
||||
|
||||
String str = TRY(String::create(""));
|
||||
|
||||
for (uint64_t i = 0; i < size; i++) {
|
||||
|
@ -46,21 +80,36 @@ Result<StackFrame> stdlib_print(const StackFrame& stack) {
|
|||
}
|
||||
}
|
||||
|
||||
TRY(print_string(str));
|
||||
if (newline) {
|
||||
str = TRY(str.concat("\n"));
|
||||
}
|
||||
|
||||
auto nil = Value(TRY(Nil::create()));
|
||||
auto res = TRY(stack.set(0, nil));
|
||||
return str;
|
||||
}
|
||||
|
||||
res = TRY(res.ret(0));
|
||||
Result<StackFrame> stdlib_print(const StackFrame& stack) {
|
||||
auto params = TRY(stack.get(0));
|
||||
auto stack_size = TRY(stack.size());
|
||||
|
||||
return res;
|
||||
if (stack_size > 1) {
|
||||
return task_return(stack, 1);
|
||||
}
|
||||
|
||||
auto str = Value(TRY(tostring(params)));
|
||||
|
||||
return raise_task(stack, StdlibTaskId::Print, str);
|
||||
}
|
||||
|
||||
Result<StackFrame> stdlib_println(const StackFrame& stack) {
|
||||
auto res = TRY(stdlib_print(stack));
|
||||
std::cout << "\n";
|
||||
auto params = TRY(stack.get(0));
|
||||
auto stack_size = TRY(stack.size());
|
||||
|
||||
return res;
|
||||
if (stack_size > 1) {
|
||||
return task_return(stack, 1);
|
||||
}
|
||||
|
||||
auto str = Value(TRY(tostring(params, true)));
|
||||
return raise_task(stack, StdlibTaskId::Print, str);
|
||||
}
|
||||
|
||||
Result<StackFrame> stdlib_prn(const StackFrame& stack) {
|
||||
|
@ -307,21 +356,7 @@ Result<StackFrame> stdlib_raise(const StackFrame& stack) {
|
|||
auto stack_size = TRY(stack.size());
|
||||
|
||||
if (stack_size > 1) {
|
||||
auto result = TRY(stack.get(1));
|
||||
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));
|
||||
|
||||
return res;
|
||||
return task_return(stack, 1);
|
||||
}
|
||||
|
||||
auto params = TRY(stack.get(0));
|
||||
|
@ -347,7 +382,8 @@ Result<StackFrame> stdlib_task(const StackFrame& stack) {
|
|||
|
||||
Value task_params = TRY(params_array.slice(1, size));
|
||||
|
||||
auto val = Value(TRY(Task::create((uint64_t)task_id.to<Int64>()->value(), *task_params.to<Array>())));
|
||||
auto val = Value(TRY(Task::create((uint64_t)task_id.to<Int64>()->value(),
|
||||
*task_params.to<Array>())));
|
||||
|
||||
auto res = TRY(stack.set(0, val));
|
||||
|
||||
|
@ -389,7 +425,8 @@ Result<Value> stdlib_task_print(const Array& params) {
|
|||
auto size = TRY(params.size());
|
||||
|
||||
if (size != 1) {
|
||||
auto err = Value(TRY(Error::create("argument-count-mismatch", "Argument count mismatch")));
|
||||
auto err = Value(TRY(
|
||||
Error::create("argument-count-mismatch", "Argument count mismatch")));
|
||||
return ERROR_OBJ(ArgumentCountMismatch, err);
|
||||
}
|
||||
|
||||
|
@ -404,15 +441,13 @@ Result<Value> stdlib_task_print(const Array& params) {
|
|||
return Value(TRY(Nil::create()));
|
||||
}
|
||||
|
||||
#define STDLIB_TASK(name, id) \
|
||||
[(uint64_t)StdlibTaskId::id] = {#name, StdlibTaskId::id, \
|
||||
stdlib_task_##name}
|
||||
#define STDLIB_TASK(name, id) \
|
||||
[(uint64_t)StdlibTaskId::id] = {#name, StdlibTaskId::id, stdlib_task_##name}
|
||||
|
||||
static StdlibTaskEntry task_entries[] = {
|
||||
STDLIB_TASK(unknown, Unknown),
|
||||
STDLIB_TASK(print, Print),
|
||||
[(uint64_t)StdlibTaskId::Max] = {0, StdlibTaskId::Max,
|
||||
stdlib_task_unknown},
|
||||
[(uint64_t)StdlibTaskId::Max] = {0, StdlibTaskId::Max, stdlib_task_unknown},
|
||||
};
|
||||
|
||||
// TODO: this just scans through the array of functions linearly every time.
|
||||
|
@ -466,7 +501,6 @@ Result<const char*> get_stdlib_function_name(StdlibFunctionId fun_id) {
|
|||
return function_entries[(uint64_t)fun_id].name;
|
||||
}
|
||||
|
||||
|
||||
StdlibTaskEntry get_task_entry(const char* name) {
|
||||
for (uint64_t i = 1; i < (uint64_t)StdlibTaskId::Max; i++) {
|
||||
if (strcmp(task_entries[i].name, name) == 0) {
|
||||
|
@ -497,8 +531,7 @@ Result<StdlibTaskId> get_stdlib_task(const Symbol& name) {
|
|||
return task_id;
|
||||
}
|
||||
|
||||
Result<Value> call_stdlib_task(StdlibTaskId fun_id,
|
||||
const Array& params) {
|
||||
Result<Value> call_stdlib_task(StdlibTaskId fun_id, const Array& params) {
|
||||
if (fun_id == StdlibTaskId(0) || fun_id >= StdlibTaskId::Max) {
|
||||
return ERROR(KeyError);
|
||||
}
|
||||
|
|
|
@ -103,6 +103,7 @@ Result<void> run_repl() {
|
|||
auto backtrace = TRY(vm.backtrace(2));
|
||||
print_error(maybe_res, backtrace);
|
||||
}
|
||||
std::cout << std::flush;
|
||||
}
|
||||
|
||||
return Result<void>();
|
||||
|
|
Loading…
Reference in a new issue