Add continuation type
This commit is contained in:
parent
a81b54a37a
commit
4a7afa0626
8 changed files with 105 additions and 0 deletions
|
@ -2,6 +2,7 @@
|
|||
|
||||
#include "die.hpp"
|
||||
#include "error.hpp"
|
||||
#include "pod.hpp"
|
||||
|
||||
static Arena* current_arena = 0;
|
||||
|
||||
|
@ -95,6 +96,8 @@ Result<PodObject*> Arena::gc_pod(PodObject* obj) {
|
|||
return gc_stack((PodStackFrame*)obj);
|
||||
case Tag::Error:
|
||||
return gc_error((PodError*)obj);
|
||||
case Tag::Continuation:
|
||||
return gc_continuation((PodContinuation*)obj);
|
||||
}
|
||||
|
||||
return ERROR(TypeMismatch);
|
||||
|
@ -277,6 +280,16 @@ Result<PodObject*> Arena::gc_error(PodError* obj) {
|
|||
return nobj;
|
||||
}
|
||||
|
||||
Result<PodObject*> Arena::gc_continuation(PodContinuation* obj) {
|
||||
auto nobj = TRY(alloc<PodContinuation>());
|
||||
nobj->header.tag = Tag::Error;
|
||||
|
||||
nobj->props = TRY(gc_pod(obj->props.get()));
|
||||
nobj->frame = TRY(gc_pod(obj->frame.get()));
|
||||
|
||||
return nobj;
|
||||
}
|
||||
|
||||
Arena& get_arena() {
|
||||
if (current_arena == 0) die("Arena not set\n");
|
||||
return *current_arena;
|
||||
|
|
|
@ -161,6 +161,7 @@ class Arena {
|
|||
Result<PodObject*> gc_module(PodModule* obj);
|
||||
Result<PodObject*> gc_stack(PodStackFrame* obj);
|
||||
Result<PodObject*> gc_error(PodError* obj);
|
||||
Result<PodObject*> gc_continuation(PodContinuation* obj);
|
||||
|
||||
void add_root(GcRootList* node) { _gcroot.insert(node); }
|
||||
|
||||
|
|
|
@ -46,6 +46,8 @@ Result<Value> Value::create(PodObject* obj) {
|
|||
return Value(TRY(StackFrame::create((PodStackFrame*)obj)));
|
||||
case Tag::Error:
|
||||
return Value(TRY(Error::create((PodError*)obj)));
|
||||
case Tag::Continuation:
|
||||
return Value(TRY(Continuation::create((PodContinuation*)obj)));
|
||||
};
|
||||
return Value();
|
||||
}
|
||||
|
@ -498,6 +500,32 @@ Result<short> Error::cmp(const Error& rhs) const {
|
|||
return res;
|
||||
}
|
||||
|
||||
Result<Value> Continuation::copy_value() const {
|
||||
return Value(Continuation(TRY(_value.copy())));
|
||||
}
|
||||
Result<Continuation> Continuation::copy() const {
|
||||
return Continuation(TRY(_value.copy()));
|
||||
}
|
||||
|
||||
Result<Value> Continuation::props() const {
|
||||
return Value::create(_value->props.get());
|
||||
}
|
||||
Result<Value> Continuation::frame() const {
|
||||
return Value::create(_value->frame.get());
|
||||
}
|
||||
|
||||
Result<short> Continuation::cmp(const Continuation& rhs) const {
|
||||
auto lhs_props = TRY(props());
|
||||
auto rhs_props = TRY(rhs.props());
|
||||
short res = TRY(lhs_props.cmp(rhs_props));
|
||||
if (res != 0) return res;
|
||||
|
||||
auto lhs_frame = TRY(frame());
|
||||
auto rhs_frame = TRY(rhs.frame());
|
||||
res = TRY(lhs_frame.cmp(rhs_frame));
|
||||
return res;
|
||||
}
|
||||
|
||||
Result<Pair> Pair::create(const Value& first, const Value& rest) {
|
||||
auto pod = TRY(arena_alloc<PodPair>());
|
||||
pod->header.tag = Tag::Pair;
|
||||
|
|
|
@ -37,6 +37,7 @@ class Error;
|
|||
class Function;
|
||||
class StdlibFunction;
|
||||
class Module;
|
||||
class Continuation;
|
||||
|
||||
short cmp_tag(Tag lhs, Tag rhs);
|
||||
|
||||
|
@ -106,6 +107,9 @@ class Object {
|
|||
virtual Result<short> cmp(const Error& rhs) const {
|
||||
return cmp_tag(tag(), Tag::Error);
|
||||
}
|
||||
virtual Result<short> cmp(const Continuation& rhs) const {
|
||||
return cmp_tag(tag(), Tag::Continuation);
|
||||
}
|
||||
|
||||
virtual Result<Value> add(const Object&) const;
|
||||
virtual Result<Value> add(const Int64&) const;
|
||||
|
@ -1210,6 +1214,48 @@ class Error : public Object {
|
|||
GcRoot<PodError> _value;
|
||||
};
|
||||
|
||||
class Continuation : public Object {
|
||||
public:
|
||||
Continuation() {}
|
||||
Continuation(Continuation&& rhs) : _value(std::move(rhs._value)) {}
|
||||
Continuation(GcRoot<PodContinuation>&& val) : _value(std::move(val)) {}
|
||||
|
||||
virtual Tag tag() const final { return Tag::Continuation; }
|
||||
virtual PodObject* pod() const final { return _value.get(); }
|
||||
virtual Result<short> cmp(const Object& rhs) const final {
|
||||
return -TRY(rhs.cmp(*this));
|
||||
}
|
||||
virtual Result<short> cmp(const Continuation& rhs) const final;
|
||||
|
||||
virtual void move(Object* obj) final {
|
||||
new (obj) Continuation(std::move(_value));
|
||||
}
|
||||
|
||||
static Result<Continuation> create(PodContinuation* obj) {
|
||||
return Continuation(TRY(MkGcRoot(obj)));
|
||||
}
|
||||
|
||||
static Result<Continuation> create(const Dict& props,
|
||||
const StackFrame& frame) {
|
||||
auto pod = TRY(arena_alloc<PodContinuation>());
|
||||
pod->header.tag = Tag::Continuation;
|
||||
|
||||
pod->props = props.pod();
|
||||
pod->frame = frame.pod();
|
||||
|
||||
return Continuation(TRY(MkGcRoot(pod)));
|
||||
}
|
||||
|
||||
Result<Value> props() const;
|
||||
Result<Value> frame() const;
|
||||
|
||||
virtual Result<Value> copy_value() const final;
|
||||
Result<Continuation> copy() const;
|
||||
|
||||
private:
|
||||
GcRoot<PodContinuation> _value;
|
||||
};
|
||||
|
||||
// note: this class doesn't perform proper destruction of objects in some cases
|
||||
class Value {
|
||||
public:
|
||||
|
|
|
@ -239,6 +239,7 @@ Result<Expression> Compiler::compile_expr(Context& context, const Value& expr) {
|
|||
case Tag::Module:
|
||||
case Tag::StackFrame:
|
||||
case Tag::Error:
|
||||
case Tag::Continuation:
|
||||
return ERROR(TypeMismatch);
|
||||
}
|
||||
return ERROR(TypeMismatch);
|
||||
|
|
|
@ -25,6 +25,7 @@ enum class Tag : uint8_t {
|
|||
Module,
|
||||
StackFrame,
|
||||
Error,
|
||||
Continuation,
|
||||
};
|
||||
|
||||
template <class T>
|
||||
|
@ -211,6 +212,14 @@ class PodError final : public PodObject {
|
|||
OffPtr<PodObject> message;
|
||||
};
|
||||
|
||||
class PodContinuation final : public PodObject {
|
||||
public:
|
||||
PodContinuation() : PodObject(Tag::Continuation) {};
|
||||
|
||||
OffPtr<PodObject> props;
|
||||
OffPtr<PodObject> frame;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
class Ptr {
|
||||
public:
|
||||
|
|
|
@ -43,6 +43,8 @@ Result<String> Writer::write_one(const Value& obj) {
|
|||
return write_stack(*obj.to<StackFrame>());
|
||||
case Tag::Error:
|
||||
return write_error(*obj.to<Error>());
|
||||
case Tag::Continuation:
|
||||
return write_continuation(*obj.to<Continuation>());
|
||||
};
|
||||
return String();
|
||||
}
|
||||
|
@ -397,6 +399,10 @@ Result<String> Writer::write_error(const Error& val) {
|
|||
return res;
|
||||
}
|
||||
|
||||
Result<String> Writer::write_continuation(const Continuation& val) {
|
||||
return TRY(String::create("#<continuation>"));
|
||||
}
|
||||
|
||||
Result<String> write_one(const Value& value) {
|
||||
auto w = Writer();
|
||||
return w.write_one(value);
|
||||
|
|
|
@ -29,6 +29,7 @@ class Writer {
|
|||
Result<String> write_module(const Module& val);
|
||||
Result<String> write_stack(const StackFrame& val);
|
||||
Result<String> write_error(const Error& val);
|
||||
Result<String> write_continuation(const Continuation& val);
|
||||
};
|
||||
|
||||
Result<String> write_one(const Value& value);
|
||||
|
|
Loading…
Reference in a new issue