Return compiled function from the compile()
This commit is contained in:
parent
d3471ed1af
commit
f305901121
10 changed files with 192 additions and 60 deletions
|
@ -81,6 +81,8 @@ Result<PodObject*> Arena::gc_pod(PodObject* obj) {
|
|||
return gc_dict((PodDict*)obj);
|
||||
case Tag::Opcode:
|
||||
return gc_opcode((PodOpcode*)obj);
|
||||
case Tag::Function:
|
||||
return gc_function((PodFunction*)obj);
|
||||
}
|
||||
|
||||
return ERROR(TypeMismatch);
|
||||
|
@ -192,6 +194,17 @@ Result<PodObject*> Arena::gc_opcode(PodOpcode* obj) {
|
|||
return nobj;
|
||||
}
|
||||
|
||||
Result<PodObject*> Arena::gc_function(PodFunction* obj) {
|
||||
auto nobj = TRY(alloc<PodFunction>());
|
||||
nobj->header.tag = Tag::Function;
|
||||
nobj->arity = obj->arity;
|
||||
nobj->name = TRY(gc_pod(obj->name.get()));
|
||||
nobj->constants = TRY(gc_pod(obj->constants.get()));
|
||||
nobj->code = TRY(gc_pod(obj->code.get()));
|
||||
|
||||
return nobj;
|
||||
}
|
||||
|
||||
Arena& get_arena() {
|
||||
if (current_arena == 0) die("Arena not set\n");
|
||||
return *current_arena;
|
||||
|
|
|
@ -155,6 +155,7 @@ class Arena {
|
|||
Result<PodObject*> gc_bytearray(PodByteArray* obj);
|
||||
Result<PodObject*> gc_dict(PodDict* obj);
|
||||
Result<PodObject*> gc_opcode(PodOpcode* obj);
|
||||
Result<PodObject*> gc_function(PodFunction* obj);
|
||||
|
||||
void add_root(GcRootList* node) { _gcroot.insert(node); }
|
||||
|
||||
|
|
|
@ -38,6 +38,8 @@ Result<Value> Value::create(PodObject* obj) {
|
|||
return Value(TRY(Pair::create((PodPair*)obj)));
|
||||
case Tag::Opcode:
|
||||
return Value(TRY(Opcode::create((PodOpcode*)obj)));
|
||||
case Tag::Function:
|
||||
return Value(TRY(Function::create((PodFunction*)obj)));
|
||||
};
|
||||
return Value();
|
||||
}
|
||||
|
@ -54,7 +56,7 @@ Result<Symbol> Symbol::create(String& rhs) {
|
|||
return Symbol(TRY(MkGcRoot(pod)));
|
||||
}
|
||||
|
||||
Result<ByteArray> ByteArray::create(String& str) {
|
||||
Result<ByteArray> ByteArray::create(const String& str) {
|
||||
uint64_t size = 0;
|
||||
for (uint64_t i = 0; i < str.size(); i++) {
|
||||
size += utf8_codepoint_size(TRY(str[i]));
|
||||
|
@ -105,6 +107,10 @@ Result<Value> Bool::copy() const { return Value(Bool(TRY(_value.copy()))); }
|
|||
|
||||
Result<Value> Opcode::copy() const { return Value(Opcode(TRY(_value.copy()))); }
|
||||
|
||||
Result<Value> Function::copy() const {
|
||||
return Value(Function(TRY(_value.copy())));
|
||||
}
|
||||
|
||||
Result<Pair> Pair::create(Value& first, Value& rest) {
|
||||
auto pod = TRY(arena_alloc<PodPair>());
|
||||
pod->header.tag = Tag::Pair;
|
||||
|
@ -123,6 +129,30 @@ Result<Value> Pair::rest() {
|
|||
return Value::create(val);
|
||||
}
|
||||
|
||||
Result<Function> Function::create(const Value& name, uint64_t arity,
|
||||
const Value& constants, const Value& code) {
|
||||
auto pod = TRY(arena_alloc<PodFunction>());
|
||||
pod->header.tag = Tag::Function;
|
||||
pod->arity = arity;
|
||||
pod->name = name.pod();
|
||||
pod->constants = constants.pod();
|
||||
pod->code = code.pod();
|
||||
|
||||
return Function(TRY(MkGcRoot(pod)));
|
||||
}
|
||||
|
||||
Result<Value> Function::name() const {
|
||||
return Value::create(_value->name.get());
|
||||
}
|
||||
|
||||
Result<Value> Function::code() const {
|
||||
return Value::create(_value->code.get());
|
||||
}
|
||||
|
||||
Result<Value> Function::constants() const {
|
||||
return Value::create(_value->constants.get());
|
||||
}
|
||||
|
||||
Result<Value> reverse(Value& val) {
|
||||
if (!val.is<Pair>()) return ERROR(TypeMismatch);
|
||||
|
||||
|
@ -140,7 +170,7 @@ Result<Value> reverse(Value& val) {
|
|||
return res;
|
||||
}
|
||||
|
||||
Result<void> debug_print(String& val) {
|
||||
Result<void> debug_print(const String& val) {
|
||||
auto ba = TRY(ByteArray::create(val));
|
||||
|
||||
for (uint64_t i = 0; i < ba.size(); i++) {
|
||||
|
@ -150,7 +180,7 @@ Result<void> debug_print(String& val) {
|
|||
return Result<void>();
|
||||
}
|
||||
|
||||
Result<void> debug_print(Value& val) {
|
||||
Result<void> debug_print(const Value& val) {
|
||||
auto w = Writer();
|
||||
auto s = TRY(w.write_one(val));
|
||||
return debug_print(s);
|
||||
|
|
|
@ -227,12 +227,12 @@ class ByteArray : public Object {
|
|||
return ByteArray(TRY(MkGcRoot(pod)));
|
||||
}
|
||||
|
||||
static Result<ByteArray> create(String& str);
|
||||
static Result<ByteArray> create(const String& str);
|
||||
|
||||
uint64_t size() { return _value->size; }
|
||||
uint64_t size() const { return _value->size; }
|
||||
virtual Result<Value> copy() const final;
|
||||
|
||||
Result<char> operator[](uint64_t idx) {
|
||||
Result<char> operator[](uint64_t idx) const {
|
||||
if (idx >= _value->size) return ERROR(IndexOutOfRange);
|
||||
return _value->data[idx];
|
||||
}
|
||||
|
@ -421,7 +421,7 @@ class String : public Object {
|
|||
uint64_t size() const { return _value->size; }
|
||||
virtual Result<Value> copy() const final;
|
||||
|
||||
Result<char32_t> operator[](uint64_t idx) {
|
||||
Result<char32_t> operator[](uint64_t idx) const {
|
||||
if (idx >= _value->size) return ERROR(IndexOutOfRange);
|
||||
return _value->data[idx];
|
||||
}
|
||||
|
@ -565,7 +565,7 @@ class Symbol : public Object {
|
|||
|
||||
uint64_t size() const { return _value->size; }
|
||||
|
||||
Result<char32_t> operator[](uint64_t idx) {
|
||||
Result<char32_t> operator[](uint64_t idx) const {
|
||||
if (idx >= _value->size) return ERROR(IndexOutOfRange);
|
||||
return _value->data[idx];
|
||||
}
|
||||
|
@ -659,7 +659,7 @@ class Int64 : public Object {
|
|||
return Int64(TRY(MkGcRoot(pod)));
|
||||
}
|
||||
|
||||
int64_t value() { return _value->value; }
|
||||
int64_t value() const { return _value->value; }
|
||||
|
||||
virtual Result<Value> copy() const final;
|
||||
|
||||
|
@ -699,7 +699,7 @@ class Float : public Object {
|
|||
return Float(TRY(MkGcRoot(pod)));
|
||||
}
|
||||
|
||||
double value() { return _value->value; }
|
||||
double value() const { return _value->value; }
|
||||
|
||||
virtual Result<Value> copy() const final;
|
||||
|
||||
|
@ -732,7 +732,7 @@ class Bool : public Object {
|
|||
return Bool(TRY(MkGcRoot(pod)));
|
||||
}
|
||||
|
||||
bool value() { return _value->value; }
|
||||
bool value() const { return _value->value; }
|
||||
|
||||
virtual Result<Value> copy() const final;
|
||||
|
||||
|
@ -773,17 +773,54 @@ class Opcode : public Object {
|
|||
return Opcode(TRY(MkGcRoot(pod)));
|
||||
}
|
||||
|
||||
Oc opcode() { return _value->opcode; }
|
||||
OpArg arg1() { return _value->arg1; }
|
||||
OpArg arg2() { return _value->arg2; }
|
||||
OpArg arg3() { return _value->arg3; }
|
||||
OpArg arg4() { return _value->arg4; }
|
||||
Oc opcode() const { return _value->opcode; }
|
||||
OpArg arg1() const { return _value->arg1; }
|
||||
OpArg arg2() const { return _value->arg2; }
|
||||
OpArg arg3() const { return _value->arg3; }
|
||||
OpArg arg4() const { return _value->arg4; }
|
||||
|
||||
virtual Result<Value> copy() const final;
|
||||
|
||||
private:
|
||||
GcRoot<PodOpcode> _value;
|
||||
};
|
||||
|
||||
class Function : public Object {
|
||||
public:
|
||||
Function() {}
|
||||
Function(Function&& rhs) : _value(std::move(rhs._value)) {}
|
||||
Function(GcRoot<PodFunction>&& val) : _value(std::move(val)) {}
|
||||
|
||||
virtual Tag tag() const final { return Tag::Function; }
|
||||
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 Opcode& rhs) const final { return 0; }
|
||||
|
||||
virtual void move(Object* obj) final {
|
||||
new (obj) Function(std::move(_value));
|
||||
}
|
||||
|
||||
static Result<Function> create(PodFunction* obj) {
|
||||
return Function(TRY(MkGcRoot(obj)));
|
||||
}
|
||||
|
||||
static Result<Function> create(const Value& name, uint64_t arity,
|
||||
const Value& constants, const Value& code);
|
||||
|
||||
uint64_t arity() { return _value->arity; }
|
||||
|
||||
Result<Value> name() const;
|
||||
Result<Value> code() const;
|
||||
Result<Value> constants() const;
|
||||
|
||||
virtual Result<Value> copy() const final;
|
||||
|
||||
private:
|
||||
GcRoot<PodFunction> _value;
|
||||
};
|
||||
|
||||
// note: this class doesn't perform proper destruction of objects in some cases
|
||||
class Value {
|
||||
public:
|
||||
|
@ -830,7 +867,7 @@ class Value {
|
|||
}
|
||||
|
||||
PodObject* pod() const { return ((Object*)buf)->pod(); }
|
||||
Tag tag() { return ((Object*)buf)->tag(); }
|
||||
Tag tag() const { return ((Object*)buf)->tag(); }
|
||||
|
||||
Object& operator*() { return *(Object*)(buf); }
|
||||
Object* operator->() { return (Object*)(buf); }
|
||||
|
@ -859,8 +896,8 @@ Result<Value> syntax_unwrap(Value& val);
|
|||
|
||||
Result<Value> reverse(Value& val);
|
||||
|
||||
Result<void> debug_print(String& val);
|
||||
Result<void> debug_print(Value& val);
|
||||
Result<void> debug_print(const String& val);
|
||||
Result<void> debug_print(const Value& val);
|
||||
|
||||
template <class K, class V>
|
||||
Result<Dict> Dict::insert(const K& key, const V& value) {
|
||||
|
|
|
@ -64,12 +64,16 @@ Result<Value> Compiler::compile(Value& expr) {
|
|||
auto context = TRY(Context::create());
|
||||
|
||||
auto ex = TRY(compile_expr(context, expr));
|
||||
TRY(ex.add_opcode(Oc::Ret, {0, (int64_t)ex.reg}));
|
||||
|
||||
Value name = TRY(Nil::create());
|
||||
Value constants = TRY(context.constants.copy());
|
||||
Value code = TRY(ex.code.copy());
|
||||
TRY(debug_print(constants));
|
||||
TRY(debug_print(code));
|
||||
return ERROR(NotImplemented);
|
||||
// TRY(debug_print(constants));
|
||||
// TRY(debug_print(code));
|
||||
|
||||
auto fun = TRY(Function::create(name, 0, constants, code));
|
||||
return Value(std::move(fun));
|
||||
}
|
||||
|
||||
Result<Expression> Compiler::compile_expr(Context& context, Value& expr) {
|
||||
|
@ -88,6 +92,7 @@ Result<Expression> Compiler::compile_expr(Context& context, Value& expr) {
|
|||
case Tag::ByteArray:
|
||||
case Tag::Dict:
|
||||
case Tag::Opcode:
|
||||
case Tag::Function:
|
||||
return ERROR(TypeMismatch);
|
||||
}
|
||||
return ERROR(TypeMismatch);
|
||||
|
@ -185,3 +190,8 @@ Result<Expression> Compiler::compile_int64(Context& context, Int64& value) {
|
|||
ex.reg = reg;
|
||||
return std::move(ex);
|
||||
}
|
||||
|
||||
Result<Value> compile(Value& expr) {
|
||||
Compiler c = Compiler();
|
||||
return c.compile(expr);
|
||||
}
|
||||
|
|
|
@ -34,3 +34,5 @@ class Compiler {
|
|||
Result<Expression> compile_primop(Context& context, Symbol& op, Pair& expr);
|
||||
Result<Expression> compile_int64(Context& context, Int64& value);
|
||||
};
|
||||
|
||||
Result<Value> compile(Value& expr);
|
||||
|
|
11
src/pod.hpp
11
src/pod.hpp
|
@ -19,6 +19,7 @@ enum class Tag : uint8_t {
|
|||
ByteArray,
|
||||
Dict,
|
||||
Opcode,
|
||||
Function,
|
||||
};
|
||||
|
||||
template <class T>
|
||||
|
@ -155,6 +156,16 @@ class PodOpcode final : public PodObject {
|
|||
OpArg arg4;
|
||||
};
|
||||
|
||||
class PodFunction final : public PodObject {
|
||||
public:
|
||||
PodFunction() : PodObject(Tag::Function){};
|
||||
|
||||
uint64_t arity;
|
||||
OffPtr<PodObject> name;
|
||||
OffPtr<PodObject> constants;
|
||||
OffPtr<PodObject> code;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
class Ptr {
|
||||
public:
|
||||
|
|
24
src/vli.cpp
24
src/vli.cpp
|
@ -8,19 +8,27 @@
|
|||
|
||||
StaticArena<64 * 1024 * 1024> arena;
|
||||
|
||||
int main() {
|
||||
auto s = DIEX(String::create("(* (+ 1 2 3) 4)"));
|
||||
Result<void> run() {
|
||||
auto s = TRY(String::create("(* (+ 1 2 3) 4)"));
|
||||
auto reader = Reader(s);
|
||||
|
||||
auto r = DIEX(reader.read_one());
|
||||
auto s2 = DIEX(write_one(r));
|
||||
auto r = TRY(reader.read_one());
|
||||
auto s2 = TRY(write_one(r));
|
||||
|
||||
DIEX(arena_gc());
|
||||
TRY(arena_gc());
|
||||
|
||||
DIEX(debug_print(s2));
|
||||
TRY(debug_print(s2));
|
||||
|
||||
Compiler c = Compiler();
|
||||
auto compiled = DIEX(c.compile(r));
|
||||
auto compiled = TRY(compile(r));
|
||||
Function& fun = *compiled.to<Function>();
|
||||
|
||||
TRY(debug_print(TRY(fun.constants())));
|
||||
TRY(debug_print(TRY(fun.code())));
|
||||
|
||||
return Result<void>();
|
||||
}
|
||||
|
||||
int main() {
|
||||
DIEX(run());
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
#include "error.hpp"
|
||||
#include "opcode.hpp"
|
||||
|
||||
Result<String> Writer::write_one(Value& obj) {
|
||||
Result<String> Writer::write_one(const Value& obj) {
|
||||
switch (obj.tag()) {
|
||||
case Tag::Nil:
|
||||
return write_nil(*obj.to<Nil>());
|
||||
|
@ -29,11 +29,13 @@ Result<String> Writer::write_one(Value& obj) {
|
|||
return write_pair(*obj.to<Pair>());
|
||||
case Tag::Opcode:
|
||||
return write_opcode(*obj.to<Opcode>());
|
||||
case Tag::Function:
|
||||
return write_function(*obj.to<Function>());
|
||||
};
|
||||
return String();
|
||||
}
|
||||
|
||||
Result<String> Writer::write_int64(Int64& val) {
|
||||
Result<String> Writer::write_int64(const Int64& val) {
|
||||
char tmp[32];
|
||||
sprintf(tmp, "%lu", val.value());
|
||||
size_t len = strlen(tmp);
|
||||
|
@ -51,7 +53,7 @@ bool needs_dot(char* str) {
|
|||
return !has_e && !has_dot;
|
||||
}
|
||||
|
||||
Result<String> Writer::write_float(Float& val) {
|
||||
Result<String> Writer::write_float(const Float& val) {
|
||||
char tmp[32];
|
||||
sprintf(tmp, "%g", val.value());
|
||||
size_t len = strlen(tmp);
|
||||
|
@ -66,19 +68,21 @@ Result<String> Writer::write_float(Float& val) {
|
|||
return String::create(tmp);
|
||||
}
|
||||
|
||||
Result<String> Writer::write_nil(Nil& val) { return String::create("nil"); }
|
||||
Result<String> Writer::write_nil(const Nil& val) {
|
||||
return String::create("nil");
|
||||
}
|
||||
|
||||
Result<String> Writer::write_bool(Bool& val) {
|
||||
Result<String> Writer::write_bool(const Bool& val) {
|
||||
if (val.value()) return String::create("true");
|
||||
|
||||
return String::create("false");
|
||||
}
|
||||
|
||||
Result<String> Writer::write_bytearray(ByteArray& val) {
|
||||
Result<String> Writer::write_bytearray(const ByteArray& val) {
|
||||
return ERROR(NotImplemented);
|
||||
}
|
||||
|
||||
Result<String> Writer::write_string(String& val) {
|
||||
Result<String> Writer::write_string(const String& val) {
|
||||
String res = TRY(String::create("\""));
|
||||
|
||||
// TODO: optimize this
|
||||
|
@ -129,7 +133,7 @@ int is_valid_symbol_char(char32_t codepoint) {
|
|||
codepoint == '_' || codepoint == '~';
|
||||
}
|
||||
|
||||
Result<String> Writer::write_symbol(Symbol& val) {
|
||||
Result<String> Writer::write_symbol(const Symbol& val) {
|
||||
String res = TRY(String::create(""));
|
||||
|
||||
// TODO: optimize this
|
||||
|
@ -144,11 +148,11 @@ Result<String> Writer::write_symbol(Symbol& val) {
|
|||
return res;
|
||||
}
|
||||
|
||||
Result<String> Writer::write_syntax(Syntax& val) {
|
||||
Result<String> Writer::write_syntax(const Syntax& val) {
|
||||
return ERROR(NotImplemented);
|
||||
}
|
||||
|
||||
Result<String> Writer::write_pair(Pair& val) {
|
||||
Result<String> Writer::write_pair(const Pair& val) {
|
||||
String res = TRY(String::create("("));
|
||||
|
||||
Value cur = TRY(val.copy());
|
||||
|
@ -173,7 +177,7 @@ Result<String> Writer::write_pair(Pair& val) {
|
|||
return res;
|
||||
}
|
||||
|
||||
Result<String> Writer::write_array(Array& val) {
|
||||
Result<String> Writer::write_array(const Array& val) {
|
||||
String res = TRY(String::create("["));
|
||||
|
||||
bool is_first = true;
|
||||
|
@ -192,7 +196,7 @@ Result<String> Writer::write_array(Array& val) {
|
|||
return res;
|
||||
}
|
||||
|
||||
Result<String> Writer::write_dict(Dict& val) {
|
||||
Result<String> Writer::write_dict(const Dict& val) {
|
||||
String res = TRY(String::create("{"));
|
||||
|
||||
bool is_first = true;
|
||||
|
@ -217,7 +221,7 @@ Result<String> Writer::write_dict(Dict& val) {
|
|||
return res;
|
||||
}
|
||||
|
||||
Result<String> Writer::write_opcode(Opcode& val) {
|
||||
Result<String> Writer::write_opcode(const Opcode& val) {
|
||||
String res = TRY(String::create("#<opcode "));
|
||||
|
||||
const char* name = opcode_name(val.opcode());
|
||||
|
@ -272,7 +276,22 @@ Result<String> Writer::write_opcode(Opcode& val) {
|
|||
return res;
|
||||
}
|
||||
|
||||
Result<String> write_one(Value& value) {
|
||||
Result<String> Writer::write_function(const Function& val) {
|
||||
auto name = TRY(val.name());
|
||||
if (name.is<Nil>()) {
|
||||
return TRY(String::create("#<function>"));
|
||||
}
|
||||
|
||||
if (!name.is<String>()) return ERROR(TypeMismatch);
|
||||
String& name_str = *name.to<String>();
|
||||
|
||||
String res = TRY(String::create("#<function "));
|
||||
res = TRY(res.concat(name_str));
|
||||
res = TRY(res.concat(">"));
|
||||
return res;
|
||||
}
|
||||
|
||||
Result<String> write_one(const Value& value) {
|
||||
auto w = Writer();
|
||||
return w.write_one(value);
|
||||
}
|
||||
|
|
|
@ -7,28 +7,29 @@ class Writer {
|
|||
public:
|
||||
Writer(){};
|
||||
|
||||
Result<String> write_one(Value& obj);
|
||||
Result<String> write_multiple(Value& obj);
|
||||
Result<String> write_one(const Value& obj);
|
||||
Result<String> write_multiple(const Value& obj);
|
||||
|
||||
private:
|
||||
Result<String> write_int64(Int64& val);
|
||||
Result<String> write_float(Float& val);
|
||||
Result<String> write_string(String& val);
|
||||
Result<String> write_pair(Pair& val);
|
||||
Result<String> write_nil(Nil& val);
|
||||
Result<String> write_bool(Bool& val);
|
||||
Result<String> write_array(Array& val);
|
||||
Result<String> write_bytearray(ByteArray& val);
|
||||
Result<String> write_dict(Dict& val);
|
||||
Result<String> write_symbol(Symbol& val);
|
||||
Result<String> write_syntax(Syntax& val);
|
||||
Result<String> write_opcode(Opcode& val);
|
||||
Result<String> write_int64(const Int64& val);
|
||||
Result<String> write_float(const Float& val);
|
||||
Result<String> write_string(const String& val);
|
||||
Result<String> write_pair(const Pair& val);
|
||||
Result<String> write_nil(const Nil& val);
|
||||
Result<String> write_bool(const Bool& val);
|
||||
Result<String> write_array(const Array& val);
|
||||
Result<String> write_bytearray(const ByteArray& val);
|
||||
Result<String> write_dict(const Dict& val);
|
||||
Result<String> write_symbol(const Symbol& val);
|
||||
Result<String> write_syntax(const Syntax& val);
|
||||
Result<String> write_opcode(const Opcode& val);
|
||||
Result<String> write_function(const Function& val);
|
||||
};
|
||||
|
||||
Result<String> write_one(Value& value);
|
||||
Result<String> write_one(const Value& value);
|
||||
|
||||
template <class T>
|
||||
Result<String> write_one(T& value)
|
||||
Result<String> write_one(const T& value)
|
||||
requires std::derived_from<T, Object>
|
||||
{
|
||||
auto w = Writer();
|
||||
|
|
Loading…
Reference in a new issue