Extract a common interface for Value::size() to get object sizes
This commit is contained in:
parent
3c30440d65
commit
021f645fbf
6 changed files with 98 additions and 73 deletions
|
@ -51,7 +51,7 @@ Result<Value> Value::create(PodObject* obj) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Result<Symbol> Symbol::create(String& rhs) {
|
Result<Symbol> Symbol::create(String& rhs) {
|
||||||
uint64_t rhs_size = rhs.size();
|
uint64_t rhs_size = TRY(rhs.size());
|
||||||
uint64_t res_size = rhs_size;
|
uint64_t res_size = rhs_size;
|
||||||
|
|
||||||
auto pod = TRY(arena_alloc<PodSymbol>(res_size * sizeof(char32_t)));
|
auto pod = TRY(arena_alloc<PodSymbol>(res_size * sizeof(char32_t)));
|
||||||
|
@ -63,7 +63,7 @@ Result<Symbol> Symbol::create(String& rhs) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Result<String> String::create(const Symbol& rhs) {
|
Result<String> String::create(const Symbol& rhs) {
|
||||||
uint64_t rhs_size = rhs.size();
|
uint64_t rhs_size = TRY(rhs.size());
|
||||||
uint64_t res_size = rhs_size;
|
uint64_t res_size = rhs_size;
|
||||||
|
|
||||||
auto pod = TRY(arena_alloc<PodString>(res_size * sizeof(char32_t)));
|
auto pod = TRY(arena_alloc<PodString>(res_size * sizeof(char32_t)));
|
||||||
|
@ -76,7 +76,8 @@ Result<String> String::create(const Symbol& rhs) {
|
||||||
|
|
||||||
Result<ByteArray> ByteArray::create(const String& str) {
|
Result<ByteArray> ByteArray::create(const String& str) {
|
||||||
uint64_t size = 0;
|
uint64_t size = 0;
|
||||||
for (uint64_t i = 0; i < str.size(); i++) {
|
auto strsize = TRY(str.size());
|
||||||
|
for (uint64_t i = 0; i < strsize; i++) {
|
||||||
size += utf8_codepoint_size(TRY(str[i]));
|
size += utf8_codepoint_size(TRY(str[i]));
|
||||||
}
|
}
|
||||||
auto pod = TRY(arena_alloc<PodByteArray>(size * sizeof(char)));
|
auto pod = TRY(arena_alloc<PodByteArray>(size * sizeof(char)));
|
||||||
|
@ -84,7 +85,7 @@ Result<ByteArray> ByteArray::create(const String& str) {
|
||||||
pod->size = size;
|
pod->size = size;
|
||||||
|
|
||||||
char* res = pod->data;
|
char* res = pod->data;
|
||||||
for (uint64_t i = 0; i < str.size(); i++) {
|
for (uint64_t i = 0; i < strsize; i++) {
|
||||||
char32_t codepoint = TRY(str[i]);
|
char32_t codepoint = TRY(str[i]);
|
||||||
size = utf8_codepoint_size(codepoint);
|
size = utf8_codepoint_size(codepoint);
|
||||||
res = utf8_write_codepoint(res, codepoint);
|
res = utf8_write_codepoint(res, codepoint);
|
||||||
|
@ -365,9 +366,9 @@ Result<Pair> Pair::create(const Value& first, const Value& rest) {
|
||||||
|
|
||||||
Result<Pair> Pair::create(const Array& arr) {
|
Result<Pair> Pair::create(const Array& arr) {
|
||||||
Value cur = TRY(Nil::create());
|
Value cur = TRY(Nil::create());
|
||||||
|
auto size = TRY(arr.size());
|
||||||
for (uint64_t i = 0; i < arr.size(); i++) {
|
for (uint64_t i = 0; i < size; i++) {
|
||||||
Value arr_elt = TRY(arr.get(arr.size() - i - 1));
|
Value arr_elt = TRY(arr.get(size - i - 1));
|
||||||
cur = TRY(Pair::create(arr_elt, cur));
|
cur = TRY(Pair::create(arr_elt, cur));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -510,8 +511,9 @@ Result<void> debug_print(const char* val) {
|
||||||
|
|
||||||
Result<void> debug_print(const String& val) {
|
Result<void> debug_print(const String& val) {
|
||||||
auto ba = TRY(ByteArray::create(val));
|
auto ba = TRY(ByteArray::create(val));
|
||||||
|
auto size = TRY(ba.size());
|
||||||
|
|
||||||
for (uint64_t i = 0; i < ba.size(); i++) {
|
for (uint64_t i = 0; i < size; i++) {
|
||||||
std::cout << TRY(ba[i]);
|
std::cout << TRY(ba[i]);
|
||||||
}
|
}
|
||||||
std::cout << "\n";
|
std::cout << "\n";
|
||||||
|
@ -536,15 +538,16 @@ Result<Value> Array::get(const Value& key) const {
|
||||||
}
|
}
|
||||||
|
|
||||||
Result<Array> Array::append(const Value& rhs) const {
|
Result<Array> Array::append(const Value& rhs) const {
|
||||||
uint64_t res_size = size() + 1;
|
uint64_t res_size = TRY(size()) + 1;
|
||||||
|
auto size = TRY(this->size());
|
||||||
|
|
||||||
auto pod = TRY(arena_alloc<PodArray>(res_size * sizeof(OffPtr<PodObject>)));
|
auto pod = TRY(arena_alloc<PodArray>(res_size * sizeof(OffPtr<PodObject>)));
|
||||||
pod->header.tag = Tag::Array;
|
pod->header.tag = Tag::Array;
|
||||||
pod->size = res_size;
|
pod->size = res_size;
|
||||||
for (uint64_t i = 0; i < size(); i++) {
|
for (uint64_t i = 0; i < size; i++) {
|
||||||
pod->data[i] = _value->data[i].get();
|
pod->data[i] = _value->data[i].get();
|
||||||
}
|
}
|
||||||
pod->data[size()] = rhs.pod();
|
pod->data[TRY(this->size())] = rhs.pod();
|
||||||
|
|
||||||
return Array(TRY(MkGcRoot(pod)));
|
return Array(TRY(MkGcRoot(pod)));
|
||||||
}
|
}
|
||||||
|
@ -556,11 +559,12 @@ short cmp_tag(Tag lhs, Tag rhs) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Result<Dict> Dict::create(const Array& arr) {
|
Result<Dict> Dict::create(const Array& arr) {
|
||||||
if (arr.size() % 2 != 0) return ERROR(KeyError);
|
auto arr_size = TRY(arr.size());
|
||||||
|
if (arr_size % 2 != 0) return ERROR(KeyError);
|
||||||
|
|
||||||
Dict res = TRY(Dict::create());
|
Dict res = TRY(Dict::create());
|
||||||
|
|
||||||
for (uint64_t i = 0; i < arr.size() / 2; i++) {
|
for (uint64_t i = 0; i < arr_size / 2; i++) {
|
||||||
auto key = TRY(Value::create(arr._value->data[2 * i].get()));
|
auto key = TRY(Value::create(arr._value->data[2 * i].get()));
|
||||||
auto value = TRY(Value::create(arr._value->data[2 * i + 1].get()));
|
auto value = TRY(Value::create(arr._value->data[2 * i + 1].get()));
|
||||||
|
|
||||||
|
@ -572,7 +576,7 @@ Result<Dict> Dict::create(const Array& arr) {
|
||||||
|
|
||||||
Result<Value> Dict::get(const Value& key) const {
|
Result<Value> Dict::get(const Value& key) const {
|
||||||
auto pos = TRY(find(key));
|
auto pos = TRY(find(key));
|
||||||
if (pos >= size()) {
|
if (pos >= TRY(size())) {
|
||||||
return ERROR(KeyError);
|
return ERROR(KeyError);
|
||||||
}
|
}
|
||||||
auto k = TRY(Value::create(_value->data[pos * 2].get()));
|
auto k = TRY(Value::create(_value->data[pos * 2].get()));
|
||||||
|
@ -586,7 +590,8 @@ Result<Value> Dict::get(const Value& key) const {
|
||||||
|
|
||||||
Result<Dict> Dict::insert(const Value& key, const Value& value) {
|
Result<Dict> Dict::insert(const Value& key, const Value& value) {
|
||||||
auto pos = TRY(find(key));
|
auto pos = TRY(find(key));
|
||||||
auto s = size();
|
auto this_size = TRY(size());
|
||||||
|
auto s = this_size;
|
||||||
if (pos >= s) {
|
if (pos >= s) {
|
||||||
s += 1;
|
s += 1;
|
||||||
} else {
|
} else {
|
||||||
|
@ -603,7 +608,7 @@ Result<Dict> Dict::insert(const Value& key, const Value& value) {
|
||||||
if (i == pos) {
|
if (i == pos) {
|
||||||
pod->data[i * 2] = key.pod();
|
pod->data[i * 2] = key.pod();
|
||||||
pod->data[i * 2 + 1] = value.pod();
|
pod->data[i * 2 + 1] = value.pod();
|
||||||
if (s > size() && i < s - 1) {
|
if (s > this_size && i < s - 1) {
|
||||||
i++;
|
i++;
|
||||||
pod->data[i * 2] = _value->data[j * 2].get();
|
pod->data[i * 2] = _value->data[j * 2].get();
|
||||||
pod->data[i * 2 + 1] = _value->data[j * 2 + 1].get();
|
pod->data[i * 2 + 1] = _value->data[j * 2 + 1].get();
|
||||||
|
@ -619,7 +624,7 @@ Result<Dict> Dict::insert(const Value& key, const Value& value) {
|
||||||
|
|
||||||
Result<uint64_t> Dict::find(const Value& key) const {
|
Result<uint64_t> Dict::find(const Value& key) const {
|
||||||
uint64_t left = 0;
|
uint64_t left = 0;
|
||||||
uint64_t right = size();
|
uint64_t right = TRY(size());
|
||||||
uint64_t pos = (left + right) / 2;
|
uint64_t pos = (left + right) / 2;
|
||||||
while (left < right) {
|
while (left < right) {
|
||||||
auto v = TRY(Value::create(_value->data[pos * 2].get()));
|
auto v = TRY(Value::create(_value->data[pos * 2].get()));
|
||||||
|
@ -748,8 +753,8 @@ Result<short> Float::cmp(const Int64& rhs) const {
|
||||||
}
|
}
|
||||||
|
|
||||||
Result<short> Dict::cmp(const Dict& rhs) const {
|
Result<short> Dict::cmp(const Dict& rhs) const {
|
||||||
auto lsize = size() * 2;
|
auto lsize = TRY(size()) * 2;
|
||||||
auto rsize = rhs.size() * 2;
|
auto rsize = TRY(rhs.size()) * 2;
|
||||||
uint64_t i = 0;
|
uint64_t i = 0;
|
||||||
uint64_t j = 0;
|
uint64_t j = 0;
|
||||||
while (1) {
|
while (1) {
|
||||||
|
@ -769,8 +774,8 @@ Result<short> Dict::cmp(const Dict& rhs) const {
|
||||||
}
|
}
|
||||||
|
|
||||||
Result<short> Array::cmp(const Array& rhs) const {
|
Result<short> Array::cmp(const Array& rhs) const {
|
||||||
auto lsize = size();
|
auto lsize = TRY(size());
|
||||||
auto rsize = rhs.size();
|
auto rsize = TRY(rhs.size());
|
||||||
uint64_t i = 0;
|
uint64_t i = 0;
|
||||||
uint64_t j = 0;
|
uint64_t j = 0;
|
||||||
while (1) {
|
while (1) {
|
||||||
|
@ -799,6 +804,8 @@ Result<Value> Object::third() const { return ERROR(TypeMismatch); }
|
||||||
|
|
||||||
Result<Value> Object::rest() const { return ERROR(TypeMismatch); }
|
Result<Value> Object::rest() const { return ERROR(TypeMismatch); }
|
||||||
|
|
||||||
|
Result<uint64_t> Object::size() const { return ERROR(TypeMismatch); }
|
||||||
|
|
||||||
Result<bool> syntax_is_list(const Value& value) {
|
Result<bool> syntax_is_list(const Value& value) {
|
||||||
if (!value.is<Syntax>()) return value.is<Pair>();
|
if (!value.is<Syntax>()) return value.is<Pair>();
|
||||||
|
|
||||||
|
|
|
@ -129,6 +129,8 @@ class Object {
|
||||||
virtual Result<Value> third() const;
|
virtual Result<Value> third() const;
|
||||||
virtual Result<Value> rest() const;
|
virtual Result<Value> rest() const;
|
||||||
|
|
||||||
|
virtual Result<uint64_t> size() const;
|
||||||
|
|
||||||
Object() = default;
|
Object() = default;
|
||||||
Object(const Object&) = delete;
|
Object(const Object&) = delete;
|
||||||
};
|
};
|
||||||
|
@ -200,7 +202,7 @@ class Array : public Object {
|
||||||
return Array(TRY(MkGcRoot(pod)));
|
return Array(TRY(MkGcRoot(pod)));
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t size() const { return _value->size; }
|
virtual Result<uint64_t> size() const { return _value->size; }
|
||||||
virtual Result<Value> copy_value() const final;
|
virtual Result<Value> copy_value() const final;
|
||||||
Result<Array> copy() const;
|
Result<Array> copy() const;
|
||||||
|
|
||||||
|
@ -212,17 +214,17 @@ class Array : public Object {
|
||||||
Result<Array> append(const V& value) const;
|
Result<Array> append(const V& value) const;
|
||||||
|
|
||||||
Result<Array> concat(Array& rhs) {
|
Result<Array> concat(Array& rhs) {
|
||||||
uint64_t rhs_size = rhs.size();
|
uint64_t rhs_size = TRY(rhs.size());
|
||||||
uint64_t lhs_size = size();
|
uint64_t lhs_size = TRY(size());
|
||||||
uint64_t res_size = lhs_size + rhs_size;
|
uint64_t res_size = lhs_size + rhs_size;
|
||||||
|
|
||||||
auto pod = TRY(arena_alloc<PodArray>(res_size * sizeof(PodObject*)));
|
auto pod = TRY(arena_alloc<PodArray>(res_size * sizeof(PodObject*)));
|
||||||
pod->header.tag = Tag::Array;
|
pod->header.tag = Tag::Array;
|
||||||
pod->size = res_size;
|
pod->size = res_size;
|
||||||
for (uint64_t i = 0; i < size(); i++) {
|
for (uint64_t i = 0; i < lhs_size; i++) {
|
||||||
pod->data[i] = _value->data[i].get();
|
pod->data[i] = _value->data[i].get();
|
||||||
}
|
}
|
||||||
for (uint64_t i = 0; i < rhs.size(); i++) {
|
for (uint64_t i = 0; i < rhs_size; i++) {
|
||||||
pod->data[lhs_size + i] = rhs._value->data[i].get();
|
pod->data[lhs_size + i] = rhs._value->data[i].get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -294,7 +296,7 @@ class ByteArray : public Object {
|
||||||
|
|
||||||
static Result<ByteArray> create(const String& str);
|
static Result<ByteArray> create(const String& str);
|
||||||
|
|
||||||
uint64_t size() const { return _value->size; }
|
virtual Result<uint64_t> size() const final { return _value->size; }
|
||||||
virtual Result<Value> copy_value() const final;
|
virtual Result<Value> copy_value() const final;
|
||||||
Result<ByteArray> copy() const;
|
Result<ByteArray> copy() const;
|
||||||
|
|
||||||
|
@ -305,7 +307,7 @@ class ByteArray : public Object {
|
||||||
|
|
||||||
Result<ByteArray> concat(const char* rhs) {
|
Result<ByteArray> concat(const char* rhs) {
|
||||||
uint64_t rhs_size = strlen(rhs);
|
uint64_t rhs_size = strlen(rhs);
|
||||||
uint64_t lhs_size = size();
|
uint64_t lhs_size = TRY(size());
|
||||||
uint64_t res_size = lhs_size + rhs_size;
|
uint64_t res_size = lhs_size + rhs_size;
|
||||||
|
|
||||||
auto pod = TRY(arena_alloc<PodByteArray>(res_size * sizeof(char)));
|
auto pod = TRY(arena_alloc<PodByteArray>(res_size * sizeof(char)));
|
||||||
|
@ -317,7 +319,7 @@ class ByteArray : public Object {
|
||||||
}
|
}
|
||||||
|
|
||||||
Result<ByteArray> concat(const char* rhs, uint64_t rhs_size) {
|
Result<ByteArray> concat(const char* rhs, uint64_t rhs_size) {
|
||||||
uint64_t lhs_size = size();
|
uint64_t lhs_size = TRY(size());
|
||||||
uint64_t res_size = lhs_size + rhs_size;
|
uint64_t res_size = lhs_size + rhs_size;
|
||||||
|
|
||||||
auto pod = TRY(arena_alloc<PodByteArray>(res_size * sizeof(char)));
|
auto pod = TRY(arena_alloc<PodByteArray>(res_size * sizeof(char)));
|
||||||
|
@ -329,8 +331,8 @@ class ByteArray : public Object {
|
||||||
}
|
}
|
||||||
|
|
||||||
Result<ByteArray> concat(ByteArray& rhs) {
|
Result<ByteArray> concat(ByteArray& rhs) {
|
||||||
uint64_t rhs_size = rhs.size();
|
uint64_t rhs_size = TRY(rhs.size());
|
||||||
uint64_t lhs_size = size();
|
uint64_t lhs_size = TRY(size());
|
||||||
uint64_t res_size = lhs_size + rhs_size;
|
uint64_t res_size = lhs_size + rhs_size;
|
||||||
|
|
||||||
auto pod = TRY(arena_alloc<PodByteArray>(res_size * sizeof(char)));
|
auto pod = TRY(arena_alloc<PodByteArray>(res_size * sizeof(char)));
|
||||||
|
@ -400,27 +402,28 @@ class Dict : public Object {
|
||||||
Result<Dict> insert(const K& key, const V& value);
|
Result<Dict> insert(const K& key, const V& value);
|
||||||
|
|
||||||
Result<Dict> concat(Dict& rhs) {
|
Result<Dict> concat(Dict& rhs) {
|
||||||
uint64_t rhs_size = rhs.size();
|
uint64_t rhs_size = TRY(rhs.size());
|
||||||
uint64_t lhs_size = size();
|
uint64_t lhs_size = TRY(size());
|
||||||
uint64_t res_size = lhs_size + rhs_size;
|
uint64_t res_size = lhs_size + rhs_size;
|
||||||
|
|
||||||
auto pod = TRY(arena_alloc<PodDict>(2 * res_size * sizeof(PodObject*)));
|
auto pod = TRY(arena_alloc<PodDict>(2 * res_size * sizeof(PodObject*)));
|
||||||
pod->size = res_size;
|
pod->size = res_size;
|
||||||
|
|
||||||
for (uint64_t i = 0; i < 2 * size(); i++) {
|
for (uint64_t i = 0; i < 2 * lhs_size; i++) {
|
||||||
pod->data[i] = _value->data[i];
|
pod->data[i] = _value->data[i];
|
||||||
}
|
}
|
||||||
for (uint64_t i = 2 * size(); i < 2 * rhs.size(); i++) {
|
for (uint64_t i = 2 * lhs_size; i < 2 * rhs_size; i++) {
|
||||||
pod->data[i] = rhs._value->data[i];
|
pod->data[i] = rhs._value->data[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
return Dict(TRY(MkGcRoot(pod)));
|
return Dict(TRY(MkGcRoot(pod)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual Result<uint64_t> size() const final { return _value->size; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Result<uint64_t> find(const Value& key) const;
|
Result<uint64_t> find(const Value& key) const;
|
||||||
|
|
||||||
uint64_t size() const { return _value->size; }
|
|
||||||
GcRoot<PodDict> _value;
|
GcRoot<PodDict> _value;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -441,8 +444,8 @@ class String : public Object {
|
||||||
return -TRY(rhs.cmp(*this));
|
return -TRY(rhs.cmp(*this));
|
||||||
}
|
}
|
||||||
virtual Result<short> cmp(const String& rhs) const final {
|
virtual Result<short> cmp(const String& rhs) const final {
|
||||||
auto lsize = size();
|
auto lsize = TRY(size());
|
||||||
auto rsize = rhs.size();
|
auto rsize = TRY(rhs.size());
|
||||||
uint64_t i = 0;
|
uint64_t i = 0;
|
||||||
uint64_t j = 0;
|
uint64_t j = 0;
|
||||||
while (1) {
|
while (1) {
|
||||||
|
@ -489,7 +492,7 @@ class String : public Object {
|
||||||
return String(TRY(MkGcRoot(pod)));
|
return String(TRY(MkGcRoot(pod)));
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t size() const { return _value->size; }
|
virtual Result<uint64_t> size() const final { return _value->size; }
|
||||||
virtual Result<Value> copy_value() const final;
|
virtual Result<Value> copy_value() const final;
|
||||||
Result<String> copy() const;
|
Result<String> copy() const;
|
||||||
|
|
||||||
|
@ -499,7 +502,7 @@ class String : public Object {
|
||||||
}
|
}
|
||||||
|
|
||||||
Result<String> concat(const char* rhs, uint64_t rhs_size) {
|
Result<String> concat(const char* rhs, uint64_t rhs_size) {
|
||||||
uint64_t lhs_size = size();
|
uint64_t lhs_size = TRY(size());
|
||||||
uint64_t res_size = lhs_size + rhs_size;
|
uint64_t res_size = lhs_size + rhs_size;
|
||||||
|
|
||||||
auto pod = TRY(arena_alloc<PodString>(res_size * sizeof(char32_t)));
|
auto pod = TRY(arena_alloc<PodString>(res_size * sizeof(char32_t)));
|
||||||
|
@ -514,7 +517,7 @@ class String : public Object {
|
||||||
Result<String> concat(const char* rhs) { return concat(rhs, strlen(rhs)); }
|
Result<String> concat(const char* rhs) { return concat(rhs, strlen(rhs)); }
|
||||||
|
|
||||||
Result<String> concat(const char32_t* rhs, uint64_t rhs_size) {
|
Result<String> concat(const char32_t* rhs, uint64_t rhs_size) {
|
||||||
uint64_t lhs_size = size();
|
uint64_t lhs_size = TRY(size());
|
||||||
uint64_t res_size = lhs_size + rhs_size;
|
uint64_t res_size = lhs_size + rhs_size;
|
||||||
|
|
||||||
auto pod = TRY(arena_alloc<PodString>(res_size * sizeof(char32_t)));
|
auto pod = TRY(arena_alloc<PodString>(res_size * sizeof(char32_t)));
|
||||||
|
@ -527,8 +530,8 @@ class String : public Object {
|
||||||
}
|
}
|
||||||
|
|
||||||
Result<String> concat(String& rhs) {
|
Result<String> concat(String& rhs) {
|
||||||
uint64_t rhs_size = rhs.size();
|
uint64_t rhs_size = TRY(rhs.size());
|
||||||
uint64_t lhs_size = size();
|
uint64_t lhs_size = TRY(size());
|
||||||
uint64_t res_size = lhs_size + rhs_size;
|
uint64_t res_size = lhs_size + rhs_size;
|
||||||
|
|
||||||
auto pod = TRY(arena_alloc<PodString>(res_size * sizeof(char32_t)));
|
auto pod = TRY(arena_alloc<PodString>(res_size * sizeof(char32_t)));
|
||||||
|
@ -570,8 +573,8 @@ class Symbol : public Object {
|
||||||
return -TRY(rhs.cmp(*this));
|
return -TRY(rhs.cmp(*this));
|
||||||
}
|
}
|
||||||
virtual Result<short> cmp(const Symbol& rhs) const final {
|
virtual Result<short> cmp(const Symbol& rhs) const final {
|
||||||
auto lsize = size();
|
auto lsize = TRY(size());
|
||||||
auto rsize = rhs.size();
|
auto rsize = TRY(rhs.size());
|
||||||
uint64_t i = 0;
|
uint64_t i = 0;
|
||||||
uint64_t j = 0;
|
uint64_t j = 0;
|
||||||
while (1) {
|
while (1) {
|
||||||
|
@ -590,7 +593,7 @@ class Symbol : public Object {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
virtual Result<short> cmp(const char* rhs) const final {
|
virtual Result<short> cmp(const char* rhs) const final {
|
||||||
auto lsize = size();
|
auto lsize = TRY(size());
|
||||||
auto rsize = strlen(rhs);
|
auto rsize = strlen(rhs);
|
||||||
uint64_t i = 0;
|
uint64_t i = 0;
|
||||||
uint64_t j = 0;
|
uint64_t j = 0;
|
||||||
|
@ -639,7 +642,7 @@ class Symbol : public Object {
|
||||||
virtual Result<Value> copy_value() const final;
|
virtual Result<Value> copy_value() const final;
|
||||||
Result<Symbol> copy() const;
|
Result<Symbol> copy() const;
|
||||||
|
|
||||||
uint64_t size() const { return _value->size; }
|
virtual Result<uint64_t> size() const final { return _value->size; }
|
||||||
|
|
||||||
Result<char32_t> operator[](uint64_t idx) const {
|
Result<char32_t> operator[](uint64_t idx) const {
|
||||||
if (idx >= _value->size) return ERROR(IndexOutOfRange);
|
if (idx >= _value->size) return ERROR(IndexOutOfRange);
|
||||||
|
|
|
@ -61,7 +61,7 @@ struct Context {
|
||||||
return idx.value().to<Int64>()->value();
|
return idx.value().to<Int64>()->value();
|
||||||
}
|
}
|
||||||
|
|
||||||
int64_t i = constants.size();
|
int64_t i = TRY(constants.size());
|
||||||
|
|
||||||
constants = TRY(constants.append(val));
|
constants = TRY(constants.append(val));
|
||||||
constants_dict = TRY(constants_dict.insert(val, TRY(Value::create(i))));
|
constants_dict = TRY(constants_dict.insert(val, TRY(Value::create(i))));
|
||||||
|
@ -132,7 +132,7 @@ struct Context {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int64_t i = closures.size();
|
int64_t i = TRY(closures.size());
|
||||||
closures = TRY(closures.append(sym));
|
closures = TRY(closures.append(sym));
|
||||||
closures_dict = TRY(closures_dict.insert(sym, TRY(Value::create(i))));
|
closures_dict = TRY(closures_dict.insert(sym, TRY(Value::create(i))));
|
||||||
|
|
||||||
|
@ -423,10 +423,10 @@ Result<Expression> Compiler::compile_if(Context& context, Symbol& op,
|
||||||
TRY(ex.add_opcode(Oc::Equal, {0, (int64_t)firstreg}, {1, (int64_t)true_const},
|
TRY(ex.add_opcode(Oc::Equal, {0, (int64_t)firstreg}, {1, (int64_t)true_const},
|
||||||
{0, (int64_t)0}));
|
{0, (int64_t)0}));
|
||||||
|
|
||||||
TRY(ex.add_opcode(Oc::Jump, {0, (int64_t)option1_comp.code.size() + 2}));
|
TRY(ex.add_opcode(Oc::Jump, {0, (int64_t)TRY(option1_comp.code.size()) + 2}));
|
||||||
|
|
||||||
ex.add_code(option1_comp.code);
|
ex.add_code(option1_comp.code);
|
||||||
TRY(ex.add_opcode(Oc::Jump, {0, (int64_t)option2_comp.code.size() + 1}));
|
TRY(ex.add_opcode(Oc::Jump, {0, (int64_t)TRY(option2_comp.code.size()) + 1}));
|
||||||
ex.add_code(option2_comp.code);
|
ex.add_code(option2_comp.code);
|
||||||
|
|
||||||
uint64_t option2_reg = option2_comp.reg;
|
uint64_t option2_reg = option2_comp.reg;
|
||||||
|
@ -468,7 +468,7 @@ Result<Expression> Compiler::compile_and(Context& context, Symbol& op,
|
||||||
if (!is_first) {
|
if (!is_first) {
|
||||||
TRY(ex.add_opcode(Oc::Equal, {0, (int64_t)prev_reg}, {1, (int64_t)true_c},
|
TRY(ex.add_opcode(Oc::Equal, {0, (int64_t)prev_reg}, {1, (int64_t)true_c},
|
||||||
{0, (int64_t)0}));
|
{0, (int64_t)0}));
|
||||||
TRY(ex.add_opcode(Oc::Jump, {0, (int64_t)param_ex.code.size() + 2}));
|
TRY(ex.add_opcode(Oc::Jump, {0, (int64_t)TRY(param_ex.code.size()) + 2}));
|
||||||
}
|
}
|
||||||
prev_reg = param_ex.reg;
|
prev_reg = param_ex.reg;
|
||||||
TRY(ex.add_code(param_ex.code));
|
TRY(ex.add_code(param_ex.code));
|
||||||
|
@ -515,7 +515,7 @@ Result<Expression> Compiler::compile_or(Context& context, Symbol& op,
|
||||||
if (!is_first) {
|
if (!is_first) {
|
||||||
TRY(ex.add_opcode(Oc::Equal, {0, (int64_t)prev_reg}, {1, (int64_t)true_c},
|
TRY(ex.add_opcode(Oc::Equal, {0, (int64_t)prev_reg}, {1, (int64_t)true_c},
|
||||||
{0, (int64_t)1}));
|
{0, (int64_t)1}));
|
||||||
TRY(ex.add_opcode(Oc::Jump, {0, (int64_t)param_ex.code.size() + 2}));
|
TRY(ex.add_opcode(Oc::Jump, {0, (int64_t)TRY(param_ex.code.size()) + 2}));
|
||||||
}
|
}
|
||||||
prev_reg = param_ex.reg;
|
prev_reg = param_ex.reg;
|
||||||
TRY(ex.add_code(param_ex.code));
|
TRY(ex.add_code(param_ex.code));
|
||||||
|
@ -685,7 +685,7 @@ Result<Expression> Compiler::compile_fn(Context& context, Symbol& op,
|
||||||
|
|
||||||
Expression ex_res = TRY(Expression::create());
|
Expression ex_res = TRY(Expression::create());
|
||||||
|
|
||||||
if (ctx.closures.size() == 0) {
|
if (TRY(ctx.closures.size()) == 0) {
|
||||||
int64_t c = TRY(context.add_const(TRY(fun.copy())));
|
int64_t c = TRY(context.add_const(TRY(fun.copy())));
|
||||||
|
|
||||||
if (context.toplevel && !name.is<Nil>()) {
|
if (context.toplevel && !name.is<Nil>()) {
|
||||||
|
@ -707,7 +707,8 @@ Result<Expression> Compiler::compile_fn(Context& context, Symbol& op,
|
||||||
uint64_t reg = context.alloc_reg();
|
uint64_t reg = context.alloc_reg();
|
||||||
TRY(ex_res.add_opcode(Oc::Mov, {0, (int64_t)reg}, {1, (int64_t)c}));
|
TRY(ex_res.add_opcode(Oc::Mov, {0, (int64_t)reg}, {1, (int64_t)c}));
|
||||||
|
|
||||||
for (uint64_t i = 0; i < ctx.closures.size(); i++) {
|
auto closures_size = TRY(ctx.closures.size());
|
||||||
|
for (uint64_t i = 0; i < closures_size; i++) {
|
||||||
Value sym = TRY(ctx.closures.get(i));
|
Value sym = TRY(ctx.closures.get(i));
|
||||||
|
|
||||||
// If this is a regular variable from outer scope - it is present in a
|
// If this is a regular variable from outer scope - it is present in a
|
||||||
|
@ -738,8 +739,9 @@ Result<Expression> Compiler::compile_fn(Context& context, Symbol& op,
|
||||||
TRY(ex_res.add_opcode(Oc::GlobalLoad, {0, (int64_t)vr}, {1, (int64_t)c}));
|
TRY(ex_res.add_opcode(Oc::GlobalLoad, {0, (int64_t)vr}, {1, (int64_t)c}));
|
||||||
}
|
}
|
||||||
|
|
||||||
TRY(ex_res.add_opcode(Oc::MakeClosure, {0, (int64_t)reg},
|
TRY(ex_res.add_opcode(
|
||||||
{0, (int64_t)reg + (int64_t)ctx.closures.size() + 1}));
|
Oc::MakeClosure, {0, (int64_t)reg},
|
||||||
|
{0, (int64_t)reg + (int64_t)TRY(ctx.closures.size()) + 1}));
|
||||||
|
|
||||||
if (context.toplevel && !name.is<Nil>()) {
|
if (context.toplevel && !name.is<Nil>()) {
|
||||||
int64_t gname = TRY(context.add_const(name));
|
int64_t gname = TRY(context.add_const(name));
|
||||||
|
@ -953,7 +955,7 @@ Result<Expression> Compiler::compile_symbol(Context& context,
|
||||||
if (unwrapped.is<Symbol>()) {
|
if (unwrapped.is<Symbol>()) {
|
||||||
Symbol& sym = *unwrapped.to<Symbol>();
|
Symbol& sym = *unwrapped.to<Symbol>();
|
||||||
|
|
||||||
if (sym.size() > 0 && TRY(sym[0]) == ':') {
|
if (TRY(sym.size()) > 0 && TRY(sym[0]) == ':') {
|
||||||
int64_t c = TRY(context.add_const(unwrapped));
|
int64_t c = TRY(context.add_const(unwrapped));
|
||||||
|
|
||||||
uint64_t reg = context.alloc_reg();
|
uint64_t reg = context.alloc_reg();
|
||||||
|
|
|
@ -559,7 +559,12 @@ char32_t Reader::get(size_t offset) {
|
||||||
|
|
||||||
bool Reader::is_eol() { return match('\n') || match('\r'); }
|
bool Reader::is_eol() { return match('\n') || match('\r'); }
|
||||||
|
|
||||||
bool Reader::is_eof() { return position_.offset == _str.size(); }
|
bool Reader::is_eof() {
|
||||||
|
// DIEX is here instead of "try" because String::size() can never fail.
|
||||||
|
// The result is wrapped to Result<> because of common interface with
|
||||||
|
// other value types.
|
||||||
|
return position_.offset == DIEX(_str.size());
|
||||||
|
}
|
||||||
|
|
||||||
bool Reader::is_whitespace() {
|
bool Reader::is_whitespace() {
|
||||||
return match(' ') || match('\t') || match('\v') || match('\f');
|
return match(' ') || match('\t') || match('\v') || match('\f');
|
||||||
|
|
|
@ -19,8 +19,9 @@ Result<Value> stdlib_unknown(const Array& params) {
|
||||||
|
|
||||||
Result<void> print_string(const String& s) {
|
Result<void> print_string(const String& s) {
|
||||||
auto ba = TRY(ByteArray::create(s));
|
auto ba = TRY(ByteArray::create(s));
|
||||||
|
auto size = TRY(ba.size());
|
||||||
|
|
||||||
for (uint64_t i = 0; i < ba.size(); i++) {
|
for (uint64_t i = 0; i < size; i++) {
|
||||||
std::cout << TRY(ba[i]);
|
std::cout << TRY(ba[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,7 +29,8 @@ Result<void> print_string(const String& s) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Result<Value> stdlib_print(const Array& params) {
|
Result<Value> stdlib_print(const Array& params) {
|
||||||
for (uint64_t i = 0; i < params.size(); i++) {
|
auto size = TRY(params.size());
|
||||||
|
for (uint64_t i = 0; i < size; i++) {
|
||||||
Value param = TRY(params.get(i));
|
Value param = TRY(params.get(i));
|
||||||
|
|
||||||
if (i != 0) {
|
if (i != 0) {
|
||||||
|
@ -55,7 +57,8 @@ Result<Value> stdlib_println(const Array& params) {
|
||||||
Result<Value> stdlib_prn(const Array& params) { return ERROR(NotImplemented); }
|
Result<Value> stdlib_prn(const Array& params) { return ERROR(NotImplemented); }
|
||||||
|
|
||||||
Result<Value> stdlib_assert(const Array& params) {
|
Result<Value> stdlib_assert(const Array& params) {
|
||||||
for (uint64_t i = 0; i < params.size(); i++) {
|
auto size = TRY(params.size());
|
||||||
|
for (uint64_t i = 0; i < size; i++) {
|
||||||
Value param = TRY(params.get(i));
|
Value param = TRY(params.get(i));
|
||||||
if (!param.is<Bool>()) return ERROR(AssertionFailed);
|
if (!param.is<Bool>()) return ERROR(AssertionFailed);
|
||||||
auto v = param.to<Bool>()->value();
|
auto v = param.to<Bool>()->value();
|
||||||
|
@ -81,7 +84,8 @@ Result<Value> stdlib_array(const Array& params) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Result<Value> stdlib_get(const Array& params) {
|
Result<Value> stdlib_get(const Array& params) {
|
||||||
if (params.size() != 2) return ERROR(ArgumentCountMismatch);
|
auto size = TRY(params.size());
|
||||||
|
if (size != 2) return ERROR(ArgumentCountMismatch);
|
||||||
Value collection = TRY(params.get(0));
|
Value collection = TRY(params.get(0));
|
||||||
Value key = TRY(params.get(1));
|
Value key = TRY(params.get(1));
|
||||||
return TRY(collection.get(key));
|
return TRY(collection.get(key));
|
||||||
|
@ -89,7 +93,8 @@ Result<Value> stdlib_get(const Array& params) {
|
||||||
|
|
||||||
Result<Value> stdlib_srcloc(const Array& params) {
|
Result<Value> stdlib_srcloc(const Array& params) {
|
||||||
Array array_copy = TRY(params.copy());
|
Array array_copy = TRY(params.copy());
|
||||||
if (params.size() != 6) return ERROR(ArgumentCountMismatch);
|
auto size = TRY(params.size());
|
||||||
|
if (size != 6) return ERROR(ArgumentCountMismatch);
|
||||||
|
|
||||||
SourceRange sr;
|
SourceRange sr;
|
||||||
for (uint64_t i = 0; i < 6; i++) {
|
for (uint64_t i = 0; i < 6; i++) {
|
||||||
|
@ -158,14 +163,15 @@ StdlibFunctionEntry get_function_entry(const char* name) {
|
||||||
Result<StdlibFunctionId> get_stdlib_function(const Symbol& name) {
|
Result<StdlibFunctionId> get_stdlib_function(const Symbol& name) {
|
||||||
const uint64_t bufsize = 256;
|
const uint64_t bufsize = 256;
|
||||||
char buf[bufsize];
|
char buf[bufsize];
|
||||||
if (name.size() + 1 > bufsize) {
|
auto size = TRY(name.size());
|
||||||
|
if (size + 1 > bufsize) {
|
||||||
return ERROR(KeyError);
|
return ERROR(KeyError);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (uint64_t i = 0; i < name.size(); i++) {
|
for (uint64_t i = 0; i < size; i++) {
|
||||||
buf[i] = (char)TRY(name[i]);
|
buf[i] = (char)TRY(name[i]);
|
||||||
}
|
}
|
||||||
buf[name.size()] = 0;
|
buf[size] = 0;
|
||||||
|
|
||||||
StdlibFunctionId fun_id = get_function_entry(buf).fun_id;
|
StdlibFunctionId fun_id = get_function_entry(buf).fun_id;
|
||||||
if (fun_id == StdlibFunctionId::Unknown) {
|
if (fun_id == StdlibFunctionId::Unknown) {
|
||||||
|
|
|
@ -121,9 +121,9 @@ Result<String> Writer::write_bytearray(const ByteArray& val) {
|
||||||
|
|
||||||
Result<String> Writer::write_string(const String& val) {
|
Result<String> Writer::write_string(const String& val) {
|
||||||
String res = TRY(String::create("\""));
|
String res = TRY(String::create("\""));
|
||||||
|
auto size = TRY(val.size());
|
||||||
// TODO: optimize this
|
// TODO: optimize this
|
||||||
for (uint64_t i = 0; i < val.size(); i++) {
|
for (uint64_t i = 0; i < size; i++) {
|
||||||
char32_t c = TRY(val[i]);
|
char32_t c = TRY(val[i]);
|
||||||
const char* replace = 0;
|
const char* replace = 0;
|
||||||
switch (c) {
|
switch (c) {
|
||||||
|
@ -172,9 +172,9 @@ int is_valid_symbol_char(char32_t codepoint) {
|
||||||
|
|
||||||
Result<String> Writer::write_symbol(const Symbol& val) {
|
Result<String> Writer::write_symbol(const Symbol& val) {
|
||||||
String res = TRY(String::create(""));
|
String res = TRY(String::create(""));
|
||||||
|
auto size = TRY(val.size());
|
||||||
// TODO: optimize this
|
// TODO: optimize this
|
||||||
for (uint64_t i = 0; i < val.size(); i++) {
|
for (uint64_t i = 0; i < size; i++) {
|
||||||
char32_t c = TRY(val[i]);
|
char32_t c = TRY(val[i]);
|
||||||
|
|
||||||
if (!is_valid_symbol_char(c)) return ERROR(InvalidSymbol);
|
if (!is_valid_symbol_char(c)) return ERROR(InvalidSymbol);
|
||||||
|
@ -239,7 +239,8 @@ Result<String> Writer::write_array(const Array& val) {
|
||||||
String res = TRY(String::create("["));
|
String res = TRY(String::create("["));
|
||||||
|
|
||||||
bool is_first = true;
|
bool is_first = true;
|
||||||
for (uint64_t i = 0; i < val.size(); i++) {
|
auto size = TRY(val.size());
|
||||||
|
for (uint64_t i = 0; i < size; i++) {
|
||||||
Value cur = TRY(val.get(i));
|
Value cur = TRY(val.get(i));
|
||||||
|
|
||||||
if (!is_first) res = TRY(res.concat(" "));
|
if (!is_first) res = TRY(res.concat(" "));
|
||||||
|
@ -258,7 +259,8 @@ Result<String> Writer::write_dict(const Dict& val) {
|
||||||
String res = TRY(String::create("{"));
|
String res = TRY(String::create("{"));
|
||||||
|
|
||||||
bool is_first = true;
|
bool is_first = true;
|
||||||
for (uint64_t i = 0; i < val.size(); i++) {
|
auto size = TRY(val.size());
|
||||||
|
for (uint64_t i = 0; i < size; i++) {
|
||||||
Value k = TRY(Value::create(val._value->data[i * 2].get()));
|
Value k = TRY(Value::create(val._value->data[i * 2].get()));
|
||||||
Value v = TRY(Value::create(val._value->data[i * 2 + 1].get()));
|
Value v = TRY(Value::create(val._value->data[i * 2 + 1].get()));
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue