2024-07-19 01:29:30 +00:00
|
|
|
#pragma once
|
|
|
|
|
|
|
|
#include <concepts>
|
|
|
|
#include <cstdint>
|
2024-07-20 21:42:49 +00:00
|
|
|
#include <cstring>
|
2024-07-19 01:29:30 +00:00
|
|
|
#include <iostream>
|
|
|
|
|
|
|
|
#include "arena.hpp"
|
2024-08-03 17:53:14 +00:00
|
|
|
#include "error.hpp"
|
2024-08-10 17:24:16 +00:00
|
|
|
#include "opcode.hpp"
|
2024-07-19 01:29:30 +00:00
|
|
|
#include "pod.hpp"
|
2024-09-06 22:32:05 +00:00
|
|
|
#include "sourcerange.hpp"
|
2024-08-24 23:55:11 +00:00
|
|
|
#include "stdlib.hpp"
|
2024-07-28 15:40:52 +00:00
|
|
|
#include "utf8.hpp"
|
2024-07-19 01:29:30 +00:00
|
|
|
|
|
|
|
// Forward declarations
|
|
|
|
|
|
|
|
class Value;
|
2024-07-28 15:40:52 +00:00
|
|
|
class String;
|
2024-08-01 17:56:38 +00:00
|
|
|
class Nil;
|
|
|
|
class Int64;
|
|
|
|
class Float;
|
|
|
|
class Bool;
|
|
|
|
class String;
|
|
|
|
class Symbol;
|
2024-09-05 22:22:45 +00:00
|
|
|
class SrcLoc;
|
|
|
|
class Symbol;
|
2024-08-01 17:56:38 +00:00
|
|
|
class Syntax;
|
|
|
|
class Pair;
|
|
|
|
class Array;
|
2024-09-01 22:11:53 +00:00
|
|
|
class Dict;
|
2024-08-01 17:56:38 +00:00
|
|
|
class ByteArray;
|
2024-08-01 21:45:16 +00:00
|
|
|
class Writer;
|
2024-08-13 00:11:23 +00:00
|
|
|
class Opcode;
|
2024-09-12 21:43:38 +00:00
|
|
|
class StackFrame;
|
2024-09-07 16:37:12 +00:00
|
|
|
class Error;
|
2024-08-17 22:22:21 +00:00
|
|
|
class Function;
|
2024-08-24 23:55:11 +00:00
|
|
|
class StdlibFunction;
|
2024-08-23 23:28:29 +00:00
|
|
|
class Module;
|
2024-08-01 17:56:38 +00:00
|
|
|
|
|
|
|
short cmp_tag(Tag lhs, Tag rhs);
|
2024-07-19 01:29:30 +00:00
|
|
|
|
|
|
|
class Object {
|
|
|
|
public:
|
2024-08-10 17:46:20 +00:00
|
|
|
virtual Tag tag() const = 0;
|
2024-08-13 00:11:23 +00:00
|
|
|
virtual Result<Value> copy_value() const = 0;
|
2024-08-10 17:46:20 +00:00
|
|
|
virtual PodObject* pod() const = 0;
|
2024-07-29 23:14:09 +00:00
|
|
|
virtual void move(Object*) = 0;
|
2024-07-27 18:40:13 +00:00
|
|
|
virtual ~Object() = default;
|
2024-08-01 17:56:38 +00:00
|
|
|
|
2024-08-10 17:46:20 +00:00
|
|
|
virtual Result<short> cmp(const Object&) const = 0;
|
|
|
|
virtual Result<short> cmp(const Nil&) const {
|
|
|
|
return cmp_tag(tag(), Tag::Nil);
|
|
|
|
}
|
|
|
|
virtual Result<short> cmp(const Int64&) const {
|
|
|
|
return cmp_tag(tag(), Tag::Int64);
|
|
|
|
}
|
|
|
|
virtual Result<short> cmp(const Float&) const {
|
|
|
|
return cmp_tag(tag(), Tag::Float);
|
|
|
|
}
|
|
|
|
virtual Result<short> cmp(const Bool&) const {
|
|
|
|
return cmp_tag(tag(), Tag::Bool);
|
|
|
|
}
|
|
|
|
virtual Result<short> cmp(const String&) const {
|
|
|
|
return cmp_tag(tag(), Tag::String);
|
|
|
|
}
|
|
|
|
virtual Result<short> cmp(const Symbol&) const {
|
|
|
|
return cmp_tag(tag(), Tag::Symbol);
|
|
|
|
}
|
2024-09-05 22:22:45 +00:00
|
|
|
virtual Result<short> cmp(const SrcLoc&) const {
|
|
|
|
return cmp_tag(tag(), Tag::SrcLoc);
|
|
|
|
}
|
2024-08-10 17:46:20 +00:00
|
|
|
virtual Result<short> cmp(const Syntax&) const {
|
|
|
|
return cmp_tag(tag(), Tag::Syntax);
|
|
|
|
}
|
|
|
|
virtual Result<short> cmp(const Pair&) const {
|
|
|
|
return cmp_tag(tag(), Tag::Pair);
|
|
|
|
}
|
|
|
|
virtual Result<short> cmp(const Array&) const {
|
|
|
|
return cmp_tag(tag(), Tag::Array);
|
|
|
|
}
|
2024-09-01 22:11:53 +00:00
|
|
|
virtual Result<short> cmp(const Dict&) const {
|
|
|
|
return cmp_tag(tag(), Tag::Dict);
|
|
|
|
}
|
2024-08-10 17:46:20 +00:00
|
|
|
virtual Result<short> cmp(const ByteArray&) const {
|
2024-08-01 17:56:38 +00:00
|
|
|
return cmp_tag(tag(), Tag::ByteArray);
|
|
|
|
}
|
2024-08-13 00:11:23 +00:00
|
|
|
virtual Result<short> cmp(const Opcode& rhs) const {
|
|
|
|
return cmp_tag(tag(), Tag::Opcode);
|
|
|
|
}
|
2024-08-17 22:22:21 +00:00
|
|
|
virtual Result<short> cmp(const Function& rhs) const {
|
2024-08-22 16:21:05 +00:00
|
|
|
return cmp_tag(tag(), Tag::Function);
|
2024-08-17 22:22:21 +00:00
|
|
|
}
|
2024-08-24 23:55:11 +00:00
|
|
|
virtual Result<short> cmp(const StdlibFunction& rhs) const {
|
|
|
|
return cmp_tag(tag(), Tag::StdlibFunction);
|
|
|
|
}
|
2024-08-23 23:28:29 +00:00
|
|
|
virtual Result<short> cmp(const Module& rhs) const {
|
|
|
|
return cmp_tag(tag(), Tag::Module);
|
|
|
|
}
|
2024-08-13 00:11:23 +00:00
|
|
|
virtual Result<short> cmp(const char* rhs) const {
|
|
|
|
return ERROR(NotImplemented);
|
|
|
|
}
|
2024-09-12 21:43:38 +00:00
|
|
|
virtual Result<short> cmp(const StackFrame& rhs) const {
|
2024-08-13 00:11:23 +00:00
|
|
|
return ERROR(NotImplemented);
|
|
|
|
}
|
2024-09-07 16:37:12 +00:00
|
|
|
virtual Result<short> cmp(const Error& rhs) const {
|
|
|
|
return cmp_tag(tag(), Tag::Error);
|
|
|
|
}
|
2024-08-13 00:11:23 +00:00
|
|
|
|
|
|
|
virtual Result<Value> add(const Object&) const;
|
|
|
|
virtual Result<Value> add(const Int64&) const;
|
2024-08-27 19:15:22 +00:00
|
|
|
virtual Result<Value> add(const Float&) const;
|
2024-08-13 00:11:23 +00:00
|
|
|
|
|
|
|
virtual Result<Value> sub(const Object&) const;
|
|
|
|
virtual Result<Value> sub_inv(const Int64&) const;
|
2024-08-27 19:15:22 +00:00
|
|
|
virtual Result<Value> sub_inv(const Float&) const;
|
2024-08-13 00:11:23 +00:00
|
|
|
|
|
|
|
virtual Result<Value> mul(const Object&) const;
|
|
|
|
virtual Result<Value> mul(const Int64&) const;
|
2024-08-27 19:15:22 +00:00
|
|
|
virtual Result<Value> mul(const Float&) const;
|
2024-08-13 00:11:23 +00:00
|
|
|
|
|
|
|
virtual Result<Value> div(const Object&) const;
|
|
|
|
virtual Result<Value> div_inv(const Int64&) const;
|
2024-08-27 19:15:22 +00:00
|
|
|
virtual Result<Value> div_inv(const Float&) const;
|
2024-08-13 00:11:23 +00:00
|
|
|
|
2024-08-10 17:56:42 +00:00
|
|
|
virtual Result<Value> get(const Value& key) const;
|
2024-08-28 22:57:01 +00:00
|
|
|
virtual Result<Value> first() const;
|
|
|
|
virtual Result<Value> second() const;
|
2024-09-01 22:45:20 +00:00
|
|
|
virtual Result<Value> third() const;
|
2024-08-28 22:57:01 +00:00
|
|
|
virtual Result<Value> rest() const;
|
2024-08-01 17:56:38 +00:00
|
|
|
|
2024-09-10 01:12:49 +00:00
|
|
|
virtual Result<uint64_t> size() const;
|
|
|
|
|
2024-07-27 18:40:13 +00:00
|
|
|
Object() = default;
|
|
|
|
Object(const Object&) = delete;
|
2024-07-19 01:29:30 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
class Nil : public Object {
|
|
|
|
public:
|
|
|
|
Nil() {}
|
2024-07-27 18:40:13 +00:00
|
|
|
Nil(Nil&& rhs) : _value(std::move(rhs._value)) {}
|
2024-07-27 15:25:44 +00:00
|
|
|
Nil(GcRoot<PodNil>&& val) : _value(std::move(val)) {}
|
2024-07-19 01:29:30 +00:00
|
|
|
|
2024-08-10 17:46:20 +00:00
|
|
|
virtual Tag tag() const final { return Tag::Nil; }
|
|
|
|
virtual PodObject* pod() const final { return _value.get(); }
|
2024-07-27 15:25:44 +00:00
|
|
|
|
2024-08-10 17:46:20 +00:00
|
|
|
virtual Result<short> cmp(const Object& rhs) const final {
|
|
|
|
return -TRY(rhs.cmp(*this));
|
|
|
|
}
|
|
|
|
virtual Result<short> cmp(const Nil& rhs) const final { return 0; }
|
2024-08-01 17:56:38 +00:00
|
|
|
|
2024-08-09 22:45:06 +00:00
|
|
|
static Result<Nil> create(PodNil* obj) { return Nil(TRY(MkGcRoot(obj))); }
|
2024-07-27 15:25:44 +00:00
|
|
|
|
2024-08-09 22:45:06 +00:00
|
|
|
static Result<Nil> create() {
|
|
|
|
auto pod = TRY(arena_alloc<PodNil>());
|
2024-07-28 23:14:30 +00:00
|
|
|
pod->header.tag = Tag::Nil;
|
2024-07-27 15:25:44 +00:00
|
|
|
|
2024-08-09 22:45:06 +00:00
|
|
|
return Nil(TRY(MkGcRoot(pod)));
|
2024-07-27 15:25:44 +00:00
|
|
|
}
|
|
|
|
|
2024-08-13 00:11:23 +00:00
|
|
|
virtual Result<Value> copy_value() const final;
|
|
|
|
Result<Nil> copy() const;
|
2024-07-27 15:25:44 +00:00
|
|
|
|
2024-09-10 02:18:00 +00:00
|
|
|
virtual Result<uint64_t> size() const { return 0; }
|
2024-07-29 23:14:09 +00:00
|
|
|
virtual void move(Object* obj) final { new (obj) Nil(std::move(_value)); }
|
|
|
|
|
2024-07-27 15:25:44 +00:00
|
|
|
private:
|
|
|
|
GcRoot<PodNil> _value;
|
2024-07-19 01:29:30 +00:00
|
|
|
};
|
|
|
|
|
2024-07-30 22:52:23 +00:00
|
|
|
class Array : public Object {
|
|
|
|
public:
|
2024-08-28 20:51:25 +00:00
|
|
|
friend class Dict;
|
|
|
|
|
2024-07-30 22:52:23 +00:00
|
|
|
Array() {}
|
|
|
|
Array(Array&& rhs) : _value(std::move(rhs._value)) {}
|
|
|
|
Array(GcRoot<PodArray>&& val) : _value(std::move(val)) {}
|
|
|
|
|
|
|
|
Array& operator=(Array&& rhs) {
|
|
|
|
_value = std::move(rhs._value);
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
2024-08-10 17:46:20 +00:00
|
|
|
virtual Tag tag() const final { return Tag::Array; }
|
|
|
|
virtual PodObject* pod() const final { return _value.get(); }
|
|
|
|
virtual Result<short> cmp(const Object& rhs) const final {
|
|
|
|
return -TRY(rhs.cmp(*this));
|
|
|
|
}
|
2024-08-22 16:21:05 +00:00
|
|
|
virtual Result<short> cmp(const Array& rhs) const final;
|
2024-07-30 22:52:23 +00:00
|
|
|
|
|
|
|
virtual void move(Object* obj) final { new (obj) Array(std::move(_value)); }
|
|
|
|
|
2024-08-09 22:45:06 +00:00
|
|
|
static Result<Array> create(PodArray* obj) {
|
|
|
|
return Array(TRY(MkGcRoot(obj)));
|
2024-07-30 22:52:23 +00:00
|
|
|
}
|
|
|
|
|
2024-08-09 22:45:06 +00:00
|
|
|
static Result<Array> create() {
|
|
|
|
auto pod = TRY(arena_alloc<PodArray>());
|
2024-07-30 22:52:23 +00:00
|
|
|
pod->header.tag = Tag::Array;
|
|
|
|
|
|
|
|
pod->size = 0;
|
|
|
|
|
2024-08-09 22:45:06 +00:00
|
|
|
return Array(TRY(MkGcRoot(pod)));
|
2024-07-30 22:52:23 +00:00
|
|
|
}
|
|
|
|
|
2024-09-10 01:12:49 +00:00
|
|
|
virtual Result<uint64_t> size() const { return _value->size; }
|
2024-08-13 00:11:23 +00:00
|
|
|
virtual Result<Value> copy_value() const final;
|
|
|
|
Result<Array> copy() const;
|
2024-07-30 22:52:23 +00:00
|
|
|
|
2024-08-10 17:56:42 +00:00
|
|
|
Result<Value> get(uint64_t idx) const;
|
|
|
|
virtual Result<Value> get(const Value& key) const final;
|
2024-07-30 22:52:23 +00:00
|
|
|
|
2024-08-10 17:56:42 +00:00
|
|
|
Result<Array> append(const Value& rhs) const;
|
2024-08-03 23:33:17 +00:00
|
|
|
template <class V>
|
2024-08-10 17:56:42 +00:00
|
|
|
Result<Array> append(const V& value) const;
|
2024-07-30 22:52:23 +00:00
|
|
|
|
2024-08-09 22:45:06 +00:00
|
|
|
Result<Array> concat(Array& rhs) {
|
2024-09-10 01:12:49 +00:00
|
|
|
uint64_t rhs_size = TRY(rhs.size());
|
|
|
|
uint64_t lhs_size = TRY(size());
|
2024-07-30 22:52:23 +00:00
|
|
|
uint64_t res_size = lhs_size + rhs_size;
|
|
|
|
|
2024-08-09 22:45:06 +00:00
|
|
|
auto pod = TRY(arena_alloc<PodArray>(res_size * sizeof(PodObject*)));
|
2024-09-01 15:13:28 +00:00
|
|
|
pod->header.tag = Tag::Array;
|
2024-07-30 22:52:23 +00:00
|
|
|
pod->size = res_size;
|
2024-09-10 01:12:49 +00:00
|
|
|
for (uint64_t i = 0; i < lhs_size; i++) {
|
2024-08-10 20:47:07 +00:00
|
|
|
pod->data[i] = _value->data[i].get();
|
2024-08-06 19:32:55 +00:00
|
|
|
}
|
2024-09-10 01:12:49 +00:00
|
|
|
for (uint64_t i = 0; i < rhs_size; i++) {
|
2024-08-10 20:47:07 +00:00
|
|
|
pod->data[lhs_size + i] = rhs._value->data[i].get();
|
2024-08-06 19:32:55 +00:00
|
|
|
}
|
2024-07-30 22:52:23 +00:00
|
|
|
|
2024-08-09 22:45:06 +00:00
|
|
|
return Array(TRY(MkGcRoot(pod)));
|
2024-07-30 22:52:23 +00:00
|
|
|
}
|
|
|
|
|
2024-08-26 12:16:05 +00:00
|
|
|
Result<Array> slice(uint64_t start, uint64_t end) const {
|
2024-08-10 10:17:20 +00:00
|
|
|
if (start > end) return ERROR(IndexOutOfRange);
|
2024-07-30 22:52:23 +00:00
|
|
|
uint64_t res_size = end - start;
|
2024-08-09 22:45:06 +00:00
|
|
|
auto pod = TRY(arena_alloc<PodArray>(res_size * sizeof(PodObject*)));
|
2024-09-01 15:13:28 +00:00
|
|
|
pod->header.tag = Tag::Array;
|
2024-07-30 22:52:23 +00:00
|
|
|
pod->size = res_size;
|
2024-08-06 19:32:55 +00:00
|
|
|
for (uint64_t i = 0; i < end - start; i++) {
|
|
|
|
pod->data[i] = _value->data[start + i];
|
|
|
|
}
|
2024-07-30 22:52:23 +00:00
|
|
|
|
2024-08-09 22:45:06 +00:00
|
|
|
return Array(TRY(MkGcRoot(pod)));
|
2024-07-30 22:52:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
GcRoot<PodArray> _value;
|
|
|
|
};
|
|
|
|
|
2024-07-28 14:42:18 +00:00
|
|
|
class ByteArray : public Object {
|
|
|
|
public:
|
|
|
|
ByteArray() {}
|
|
|
|
ByteArray(ByteArray&& rhs) : _value(std::move(rhs._value)) {}
|
|
|
|
ByteArray(GcRoot<PodByteArray>&& val) : _value(std::move(val)) {}
|
|
|
|
|
|
|
|
ByteArray& operator=(ByteArray&& rhs) {
|
|
|
|
_value = std::move(rhs._value);
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
2024-08-10 17:46:20 +00:00
|
|
|
virtual Tag tag() const final { return Tag::ByteArray; }
|
|
|
|
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 ByteArray& rhs) const final { return 0; }
|
2024-07-28 14:42:18 +00:00
|
|
|
|
2024-07-29 23:14:09 +00:00
|
|
|
virtual void move(Object* obj) final {
|
|
|
|
new (obj) ByteArray(std::move(_value));
|
|
|
|
}
|
|
|
|
|
2024-08-09 22:45:06 +00:00
|
|
|
static Result<ByteArray> create(PodByteArray* obj) {
|
|
|
|
return ByteArray(TRY(MkGcRoot(obj)));
|
2024-07-28 14:42:18 +00:00
|
|
|
}
|
2024-08-09 22:45:06 +00:00
|
|
|
static Result<ByteArray> create(char* chars, int64_t size) {
|
|
|
|
auto pod = TRY(arena_alloc<PodByteArray>(size * sizeof(char)));
|
2024-07-28 23:14:30 +00:00
|
|
|
pod->header.tag = Tag::ByteArray;
|
2024-07-28 14:42:18 +00:00
|
|
|
|
|
|
|
memcpy(pod->data, chars, size * sizeof(char32_t));
|
|
|
|
pod->size = size;
|
|
|
|
|
2024-08-09 22:45:06 +00:00
|
|
|
return ByteArray(TRY(MkGcRoot(pod)));
|
2024-07-28 14:42:18 +00:00
|
|
|
}
|
|
|
|
|
2024-08-09 22:45:06 +00:00
|
|
|
static Result<ByteArray> create(const char* str) {
|
2024-07-28 14:42:18 +00:00
|
|
|
uint64_t size = strlen(str);
|
2024-08-09 22:45:06 +00:00
|
|
|
auto pod = TRY(arena_alloc<PodByteArray>(size * sizeof(char32_t)));
|
2024-07-28 23:14:30 +00:00
|
|
|
pod->header.tag = Tag::ByteArray;
|
2024-07-28 14:42:18 +00:00
|
|
|
|
|
|
|
memcpy(pod->data, str, size);
|
|
|
|
pod->size = size;
|
|
|
|
|
2024-08-09 22:45:06 +00:00
|
|
|
return ByteArray(TRY(MkGcRoot(pod)));
|
2024-07-28 14:42:18 +00:00
|
|
|
}
|
|
|
|
|
2024-08-11 20:37:37 +00:00
|
|
|
static Result<ByteArray> create(const String& str);
|
2024-07-28 15:40:52 +00:00
|
|
|
|
2024-09-10 01:12:49 +00:00
|
|
|
virtual Result<uint64_t> size() const final { return _value->size; }
|
2024-08-13 00:11:23 +00:00
|
|
|
virtual Result<Value> copy_value() const final;
|
|
|
|
Result<ByteArray> copy() const;
|
2024-07-28 14:42:18 +00:00
|
|
|
|
2024-08-11 20:37:37 +00:00
|
|
|
Result<char> operator[](uint64_t idx) const {
|
2024-08-10 10:17:20 +00:00
|
|
|
if (idx >= _value->size) return ERROR(IndexOutOfRange);
|
2024-07-28 14:42:18 +00:00
|
|
|
return _value->data[idx];
|
|
|
|
}
|
|
|
|
|
2024-08-09 22:45:06 +00:00
|
|
|
Result<ByteArray> concat(const char* rhs) {
|
2024-07-28 14:42:18 +00:00
|
|
|
uint64_t rhs_size = strlen(rhs);
|
2024-09-10 01:12:49 +00:00
|
|
|
uint64_t lhs_size = TRY(size());
|
2024-07-28 14:42:18 +00:00
|
|
|
uint64_t res_size = lhs_size + rhs_size;
|
|
|
|
|
2024-08-09 22:45:06 +00:00
|
|
|
auto pod = TRY(arena_alloc<PodByteArray>(res_size * sizeof(char)));
|
2024-07-28 14:42:18 +00:00
|
|
|
pod->size = res_size;
|
|
|
|
memcpy(pod->data, _value->data, sizeof(char) * lhs_size);
|
|
|
|
memcpy(pod->data, rhs + lhs_size, sizeof(char) * rhs_size);
|
|
|
|
|
2024-08-09 22:45:06 +00:00
|
|
|
return ByteArray(TRY(MkGcRoot(pod)));
|
2024-07-28 14:42:18 +00:00
|
|
|
}
|
|
|
|
|
2024-08-09 22:45:06 +00:00
|
|
|
Result<ByteArray> concat(const char* rhs, uint64_t rhs_size) {
|
2024-09-10 01:12:49 +00:00
|
|
|
uint64_t lhs_size = TRY(size());
|
2024-07-28 14:42:18 +00:00
|
|
|
uint64_t res_size = lhs_size + rhs_size;
|
|
|
|
|
2024-08-09 22:45:06 +00:00
|
|
|
auto pod = TRY(arena_alloc<PodByteArray>(res_size * sizeof(char)));
|
2024-07-28 14:42:18 +00:00
|
|
|
pod->size = res_size;
|
|
|
|
memcpy(pod->data, _value->data, sizeof(char) * lhs_size);
|
|
|
|
memcpy(pod->data, rhs + lhs_size, sizeof(char) * rhs_size);
|
|
|
|
|
2024-08-09 22:45:06 +00:00
|
|
|
return ByteArray(TRY(MkGcRoot(pod)));
|
2024-07-28 14:42:18 +00:00
|
|
|
}
|
|
|
|
|
2024-08-09 22:45:06 +00:00
|
|
|
Result<ByteArray> concat(ByteArray& rhs) {
|
2024-09-10 01:12:49 +00:00
|
|
|
uint64_t rhs_size = TRY(rhs.size());
|
|
|
|
uint64_t lhs_size = TRY(size());
|
2024-07-28 14:42:18 +00:00
|
|
|
uint64_t res_size = lhs_size + rhs_size;
|
|
|
|
|
2024-08-09 22:45:06 +00:00
|
|
|
auto pod = TRY(arena_alloc<PodByteArray>(res_size * sizeof(char)));
|
2024-07-28 14:42:18 +00:00
|
|
|
pod->size = res_size;
|
|
|
|
memcpy(pod->data, _value->data, sizeof(char) * lhs_size);
|
|
|
|
memcpy(pod->data + lhs_size, rhs._value->data, sizeof(char) * rhs_size);
|
|
|
|
|
2024-08-09 22:45:06 +00:00
|
|
|
return ByteArray(TRY(MkGcRoot(pod)));
|
2024-07-28 14:42:18 +00:00
|
|
|
}
|
|
|
|
|
2024-08-26 12:16:05 +00:00
|
|
|
Result<ByteArray> slice(uint64_t start, uint64_t end) const {
|
2024-08-10 10:17:20 +00:00
|
|
|
if (start > end) return ERROR(IndexOutOfRange);
|
2024-07-28 14:42:18 +00:00
|
|
|
uint64_t res_size = end - start;
|
2024-08-09 22:45:06 +00:00
|
|
|
auto pod = TRY(arena_alloc<PodByteArray>(res_size * sizeof(char)));
|
2024-07-28 14:42:18 +00:00
|
|
|
pod->size = res_size;
|
|
|
|
memcpy(pod->data, _value->data + start, sizeof(char) * res_size);
|
|
|
|
|
2024-08-09 22:45:06 +00:00
|
|
|
return ByteArray(TRY(MkGcRoot(pod)));
|
2024-07-28 14:42:18 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
GcRoot<PodByteArray> _value;
|
|
|
|
};
|
|
|
|
|
2024-08-01 17:56:38 +00:00
|
|
|
class Dict : public Object {
|
|
|
|
public:
|
2024-08-01 21:45:16 +00:00
|
|
|
friend class Writer;
|
2024-08-01 17:56:38 +00:00
|
|
|
Dict() {}
|
|
|
|
Dict(Dict&& rhs) : _value(std::move(rhs._value)) {}
|
|
|
|
Dict(GcRoot<PodDict>&& val) : _value(std::move(val)) {}
|
|
|
|
|
|
|
|
Dict& operator=(Dict&& rhs) {
|
|
|
|
_value = std::move(rhs._value);
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
2024-08-10 17:46:20 +00:00
|
|
|
virtual Tag tag() const final { return Tag::Dict; }
|
|
|
|
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 Dict& rhs) const final;
|
2024-08-01 17:56:38 +00:00
|
|
|
|
|
|
|
virtual void move(Object* obj) final { new (obj) Dict(std::move(_value)); }
|
|
|
|
|
2024-08-09 22:45:06 +00:00
|
|
|
static Result<Dict> create(PodDict* obj) { return Dict(TRY(MkGcRoot(obj))); }
|
2024-08-01 17:56:38 +00:00
|
|
|
|
2024-08-28 20:51:25 +00:00
|
|
|
static Result<Dict> create(const Array& arr);
|
|
|
|
|
2024-08-09 22:45:06 +00:00
|
|
|
static Result<Dict> create() {
|
|
|
|
auto pod = TRY(arena_alloc<PodDict>());
|
2024-08-01 17:56:38 +00:00
|
|
|
pod->header.tag = Tag::Dict;
|
|
|
|
|
|
|
|
pod->size = 0;
|
|
|
|
|
2024-08-09 22:45:06 +00:00
|
|
|
return Dict(TRY(MkGcRoot(pod)));
|
2024-08-01 17:56:38 +00:00
|
|
|
}
|
|
|
|
|
2024-08-13 00:11:23 +00:00
|
|
|
virtual Result<Value> copy_value() const final;
|
|
|
|
Result<Dict> copy() const;
|
2024-08-01 17:56:38 +00:00
|
|
|
|
2024-08-10 17:56:42 +00:00
|
|
|
virtual Result<Value> get(const Value& key) const final;
|
2024-08-01 17:56:38 +00:00
|
|
|
|
2024-08-10 17:46:20 +00:00
|
|
|
Result<Dict> insert(const Value& key, const Value& value);
|
2024-08-01 17:56:38 +00:00
|
|
|
|
2024-08-01 21:45:16 +00:00
|
|
|
template <class K, class V>
|
2024-08-09 22:45:06 +00:00
|
|
|
Result<Dict> insert(const K& key, const V& value);
|
2024-08-01 21:45:16 +00:00
|
|
|
|
2024-08-09 22:45:06 +00:00
|
|
|
Result<Dict> concat(Dict& rhs) {
|
2024-09-10 01:12:49 +00:00
|
|
|
uint64_t rhs_size = TRY(rhs.size());
|
|
|
|
uint64_t lhs_size = TRY(size());
|
2024-08-01 17:56:38 +00:00
|
|
|
uint64_t res_size = lhs_size + rhs_size;
|
|
|
|
|
2024-08-09 22:45:06 +00:00
|
|
|
auto pod = TRY(arena_alloc<PodDict>(2 * res_size * sizeof(PodObject*)));
|
2024-08-01 17:56:38 +00:00
|
|
|
pod->size = res_size;
|
2024-08-06 19:32:55 +00:00
|
|
|
|
2024-09-10 01:12:49 +00:00
|
|
|
for (uint64_t i = 0; i < 2 * lhs_size; i++) {
|
2024-08-06 19:32:55 +00:00
|
|
|
pod->data[i] = _value->data[i];
|
|
|
|
}
|
2024-09-10 01:12:49 +00:00
|
|
|
for (uint64_t i = 2 * lhs_size; i < 2 * rhs_size; i++) {
|
2024-08-06 19:32:55 +00:00
|
|
|
pod->data[i] = rhs._value->data[i];
|
|
|
|
}
|
2024-08-01 17:56:38 +00:00
|
|
|
|
2024-08-09 22:45:06 +00:00
|
|
|
return Dict(TRY(MkGcRoot(pod)));
|
2024-08-01 17:56:38 +00:00
|
|
|
}
|
|
|
|
|
2024-09-10 01:12:49 +00:00
|
|
|
virtual Result<uint64_t> size() const final { return _value->size; }
|
|
|
|
|
2024-08-01 17:56:38 +00:00
|
|
|
private:
|
2024-08-10 17:56:42 +00:00
|
|
|
Result<uint64_t> find(const Value& key) const;
|
2024-08-01 21:45:16 +00:00
|
|
|
|
2024-08-01 17:56:38 +00:00
|
|
|
GcRoot<PodDict> _value;
|
|
|
|
};
|
|
|
|
|
2024-07-19 01:29:30 +00:00
|
|
|
class String : public Object {
|
|
|
|
public:
|
2024-07-26 18:32:27 +00:00
|
|
|
String() {}
|
2024-07-27 18:40:13 +00:00
|
|
|
String(String&& rhs) : _value(std::move(rhs._value)) {}
|
2024-07-26 18:32:27 +00:00
|
|
|
String(GcRoot<PodString>&& val) : _value(std::move(val)) {}
|
2024-07-27 22:13:59 +00:00
|
|
|
|
|
|
|
String& operator=(String&& rhs) {
|
|
|
|
_value = std::move(rhs._value);
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
2024-08-10 17:46:20 +00:00
|
|
|
virtual Tag tag() const final { return Tag::String; }
|
|
|
|
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 String& rhs) const final {
|
2024-09-10 01:12:49 +00:00
|
|
|
auto lsize = TRY(size());
|
|
|
|
auto rsize = TRY(rhs.size());
|
2024-08-02 22:27:36 +00:00
|
|
|
uint64_t i = 0;
|
|
|
|
uint64_t j = 0;
|
|
|
|
while (1) {
|
|
|
|
if (i == lsize && j == lsize) return 0;
|
|
|
|
|
|
|
|
short cmp = short(i == lsize) - short(j == rsize);
|
|
|
|
if (cmp != 0) return cmp;
|
|
|
|
|
|
|
|
char32_t lc = _value->data[i];
|
|
|
|
char32_t rc = rhs._value->data[j];
|
|
|
|
cmp = (lc > rc) - (lc < rc);
|
|
|
|
if (cmp != 0) return cmp;
|
|
|
|
i++;
|
|
|
|
j++;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
2024-07-19 01:29:30 +00:00
|
|
|
|
2024-07-29 23:14:09 +00:00
|
|
|
virtual void move(Object* obj) final { new (obj) String(std::move(_value)); }
|
|
|
|
|
2024-08-09 22:45:06 +00:00
|
|
|
static Result<String> create(PodString* obj) {
|
|
|
|
return String(TRY(MkGcRoot(obj)));
|
2024-07-26 18:32:27 +00:00
|
|
|
}
|
2024-08-09 22:45:06 +00:00
|
|
|
static Result<String> create(char32_t* chars, int64_t size) {
|
|
|
|
auto pod = TRY(arena_alloc<PodString>(size * sizeof(char32_t)));
|
2024-07-28 23:14:30 +00:00
|
|
|
pod->header.tag = Tag::String;
|
2024-07-20 21:42:49 +00:00
|
|
|
|
2024-07-28 23:14:30 +00:00
|
|
|
memcpy(pod->data, chars, size * sizeof(char32_t));
|
|
|
|
pod->size = size;
|
2024-07-20 21:42:49 +00:00
|
|
|
|
2024-08-09 22:45:06 +00:00
|
|
|
return String(TRY(MkGcRoot(pod)));
|
2024-07-20 21:42:49 +00:00
|
|
|
}
|
|
|
|
|
2024-09-08 01:31:54 +00:00
|
|
|
static Result<String> create(const Symbol& sym);
|
|
|
|
|
2024-08-09 22:45:06 +00:00
|
|
|
static Result<String> create(const char* str) {
|
2024-07-27 00:01:38 +00:00
|
|
|
uint64_t size = strlen(str);
|
2024-08-09 22:45:06 +00:00
|
|
|
auto pod = TRY(arena_alloc<PodString>(size * sizeof(char32_t)));
|
2024-07-28 23:14:30 +00:00
|
|
|
pod->header.tag = Tag::String;
|
2024-07-27 00:01:38 +00:00
|
|
|
|
2024-07-28 23:14:30 +00:00
|
|
|
for (uint64_t i = 0; i < size; i++) pod->data[i] = str[i];
|
|
|
|
pod->size = size;
|
2024-07-27 00:01:38 +00:00
|
|
|
|
2024-08-09 22:45:06 +00:00
|
|
|
return String(TRY(MkGcRoot(pod)));
|
2024-07-27 00:01:38 +00:00
|
|
|
}
|
|
|
|
|
2024-09-10 01:12:49 +00:00
|
|
|
virtual Result<uint64_t> size() const final { return _value->size; }
|
2024-08-13 00:11:23 +00:00
|
|
|
virtual Result<Value> copy_value() const final;
|
|
|
|
Result<String> copy() const;
|
2024-07-27 00:01:38 +00:00
|
|
|
|
2024-08-11 20:37:37 +00:00
|
|
|
Result<char32_t> operator[](uint64_t idx) const {
|
2024-08-10 10:17:20 +00:00
|
|
|
if (idx >= _value->size) return ERROR(IndexOutOfRange);
|
2024-07-27 00:01:38 +00:00
|
|
|
return _value->data[idx];
|
|
|
|
}
|
|
|
|
|
2024-08-18 19:01:40 +00:00
|
|
|
Result<String> concat(const char* rhs, uint64_t rhs_size) {
|
2024-09-10 01:12:49 +00:00
|
|
|
uint64_t lhs_size = TRY(size());
|
2024-07-27 22:13:59 +00:00
|
|
|
uint64_t res_size = lhs_size + rhs_size;
|
|
|
|
|
2024-08-09 22:45:06 +00:00
|
|
|
auto pod = TRY(arena_alloc<PodString>(res_size * sizeof(char32_t)));
|
2024-07-28 23:14:30 +00:00
|
|
|
pod->header.tag = Tag::String;
|
2024-07-27 22:13:59 +00:00
|
|
|
pod->size = res_size;
|
|
|
|
memcpy(pod->data, _value->data, sizeof(char32_t) * lhs_size);
|
|
|
|
for (uint64_t i = 0; i < rhs_size; i++) pod->data[lhs_size + i] = rhs[i];
|
|
|
|
|
2024-08-09 22:45:06 +00:00
|
|
|
return String(TRY(MkGcRoot(pod)));
|
2024-07-27 22:13:59 +00:00
|
|
|
}
|
|
|
|
|
2024-08-18 19:01:40 +00:00
|
|
|
Result<String> concat(const char* rhs) { return concat(rhs, strlen(rhs)); }
|
|
|
|
|
2024-08-09 22:45:06 +00:00
|
|
|
Result<String> concat(const char32_t* rhs, uint64_t rhs_size) {
|
2024-09-10 01:12:49 +00:00
|
|
|
uint64_t lhs_size = TRY(size());
|
2024-07-27 22:13:59 +00:00
|
|
|
uint64_t res_size = lhs_size + rhs_size;
|
|
|
|
|
2024-08-09 22:45:06 +00:00
|
|
|
auto pod = TRY(arena_alloc<PodString>(res_size * sizeof(char32_t)));
|
2024-07-28 23:14:30 +00:00
|
|
|
pod->header.tag = Tag::String;
|
2024-07-27 22:13:59 +00:00
|
|
|
pod->size = res_size;
|
|
|
|
memcpy(pod->data, _value->data, sizeof(char32_t) * lhs_size);
|
|
|
|
for (uint64_t i = 0; i < rhs_size; i++) pod->data[lhs_size + i] = rhs[i];
|
|
|
|
|
2024-08-09 22:45:06 +00:00
|
|
|
return String(TRY(MkGcRoot(pod)));
|
2024-07-27 22:13:59 +00:00
|
|
|
}
|
|
|
|
|
2024-08-09 22:45:06 +00:00
|
|
|
Result<String> concat(String& rhs) {
|
2024-09-10 01:12:49 +00:00
|
|
|
uint64_t rhs_size = TRY(rhs.size());
|
|
|
|
uint64_t lhs_size = TRY(size());
|
2024-07-27 22:13:59 +00:00
|
|
|
uint64_t res_size = lhs_size + rhs_size;
|
|
|
|
|
2024-08-09 22:45:06 +00:00
|
|
|
auto pod = TRY(arena_alloc<PodString>(res_size * sizeof(char32_t)));
|
2024-07-28 23:14:30 +00:00
|
|
|
pod->header.tag = Tag::String;
|
2024-07-27 22:13:59 +00:00
|
|
|
pod->size = res_size;
|
|
|
|
memcpy(pod->data, _value->data, sizeof(char32_t) * lhs_size);
|
|
|
|
memcpy(pod->data + lhs_size, rhs._value->data, sizeof(char32_t) * rhs_size);
|
|
|
|
|
2024-08-09 22:45:06 +00:00
|
|
|
return String(TRY(MkGcRoot(pod)));
|
2024-07-27 22:13:59 +00:00
|
|
|
}
|
|
|
|
|
2024-08-26 12:16:05 +00:00
|
|
|
Result<String> slice(uint64_t start, uint64_t end) const {
|
2024-08-10 10:17:20 +00:00
|
|
|
if (start > end) return ERROR(IndexOutOfRange);
|
2024-07-27 22:13:59 +00:00
|
|
|
uint64_t res_size = end - start;
|
2024-08-09 22:45:06 +00:00
|
|
|
auto pod = TRY(arena_alloc<PodString>(res_size * sizeof(char32_t)));
|
2024-07-28 23:14:30 +00:00
|
|
|
pod->header.tag = Tag::String;
|
2024-07-27 22:13:59 +00:00
|
|
|
pod->size = res_size;
|
|
|
|
memcpy(pod->data, _value->data + start, sizeof(char32_t) * res_size);
|
|
|
|
|
2024-08-09 22:45:06 +00:00
|
|
|
return String(TRY(MkGcRoot(pod)));
|
2024-07-27 22:13:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
friend class Symbol;
|
2024-07-26 18:32:27 +00:00
|
|
|
|
2024-07-19 01:29:30 +00:00
|
|
|
private:
|
2024-07-26 18:32:27 +00:00
|
|
|
GcRoot<PodString> _value;
|
2024-07-19 01:29:30 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
class Symbol : public Object {
|
|
|
|
public:
|
2024-09-08 01:31:54 +00:00
|
|
|
friend class String;
|
|
|
|
|
2024-07-26 18:32:27 +00:00
|
|
|
Symbol() {}
|
2024-07-27 18:40:13 +00:00
|
|
|
Symbol(Symbol&& rhs) : _value(std::move(rhs._value)) {}
|
2024-07-26 18:32:27 +00:00
|
|
|
Symbol(GcRoot<PodSymbol>&& val) : _value(std::move(val)) {}
|
2024-08-10 17:46:20 +00:00
|
|
|
virtual Tag tag() const final { return Tag::Symbol; }
|
|
|
|
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 Symbol& rhs) const final {
|
2024-09-10 01:12:49 +00:00
|
|
|
auto lsize = TRY(size());
|
|
|
|
auto rsize = TRY(rhs.size());
|
2024-08-04 00:03:01 +00:00
|
|
|
uint64_t i = 0;
|
|
|
|
uint64_t j = 0;
|
|
|
|
while (1) {
|
|
|
|
if (i == lsize && j == lsize) return 0;
|
|
|
|
|
|
|
|
short cmp = short(i == lsize) - short(j == rsize);
|
|
|
|
if (cmp != 0) return cmp;
|
2024-07-19 01:29:30 +00:00
|
|
|
|
2024-08-04 00:03:01 +00:00
|
|
|
char32_t lc = _value->data[i];
|
|
|
|
char32_t rc = rhs._value->data[j];
|
|
|
|
cmp = (lc > rc) - (lc < rc);
|
|
|
|
if (cmp != 0) return cmp;
|
|
|
|
i++;
|
|
|
|
j++;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
2024-08-10 17:46:20 +00:00
|
|
|
virtual Result<short> cmp(const char* rhs) const final {
|
2024-09-10 01:12:49 +00:00
|
|
|
auto lsize = TRY(size());
|
2024-08-10 10:17:20 +00:00
|
|
|
auto rsize = strlen(rhs);
|
|
|
|
uint64_t i = 0;
|
|
|
|
uint64_t j = 0;
|
|
|
|
while (1) {
|
2024-08-23 21:21:00 +00:00
|
|
|
if (i == lsize && j == rsize) return 0;
|
2024-08-10 10:17:20 +00:00
|
|
|
|
|
|
|
short cmp = short(i == lsize) - short(j == rsize);
|
|
|
|
if (cmp != 0) return cmp;
|
|
|
|
|
|
|
|
char32_t lc = _value->data[i];
|
|
|
|
char32_t rc = rhs[j];
|
|
|
|
cmp = (lc > rc) - (lc < rc);
|
|
|
|
if (cmp != 0) return cmp;
|
|
|
|
i++;
|
|
|
|
j++;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
2024-07-29 23:14:09 +00:00
|
|
|
virtual void move(Object* obj) final { new (obj) Symbol(std::move(_value)); }
|
|
|
|
|
2024-08-09 22:45:06 +00:00
|
|
|
static Result<Symbol> create(PodSymbol* obj) {
|
|
|
|
return Symbol(TRY(MkGcRoot(obj)));
|
2024-07-26 18:32:27 +00:00
|
|
|
}
|
|
|
|
|
2024-08-09 22:45:06 +00:00
|
|
|
static Result<Symbol> create(char32_t* chars, int64_t size) {
|
|
|
|
auto pod = TRY(arena_alloc<PodSymbol>(size * sizeof(char32_t)));
|
2024-07-28 23:14:30 +00:00
|
|
|
pod->header.tag = Tag::Symbol;
|
2024-07-20 21:42:49 +00:00
|
|
|
|
2024-07-28 23:14:30 +00:00
|
|
|
memcpy(pod->data, chars, size * sizeof(char32_t));
|
2024-07-20 21:42:49 +00:00
|
|
|
|
2024-08-09 22:45:06 +00:00
|
|
|
return Symbol(TRY(MkGcRoot(pod)));
|
2024-07-20 21:42:49 +00:00
|
|
|
}
|
|
|
|
|
2024-08-09 22:45:06 +00:00
|
|
|
static Result<Symbol> create(const char* str) {
|
2024-08-04 00:03:01 +00:00
|
|
|
uint64_t size = strlen(str);
|
2024-08-09 22:45:06 +00:00
|
|
|
auto pod = TRY(arena_alloc<PodSymbol>(size * sizeof(char32_t)));
|
2024-08-04 00:03:01 +00:00
|
|
|
pod->header.tag = Tag::Symbol;
|
|
|
|
|
|
|
|
for (uint64_t i = 0; i < size; i++) pod->data[i] = str[i];
|
|
|
|
pod->size = size;
|
|
|
|
|
2024-08-09 22:45:06 +00:00
|
|
|
return Symbol(TRY(MkGcRoot(pod)));
|
2024-08-04 00:03:01 +00:00
|
|
|
}
|
|
|
|
|
2024-08-09 22:45:06 +00:00
|
|
|
static Result<Symbol> create(String& rhs);
|
2024-08-13 00:11:23 +00:00
|
|
|
virtual Result<Value> copy_value() const final;
|
|
|
|
Result<Symbol> copy() const;
|
2024-07-26 18:32:27 +00:00
|
|
|
|
2024-09-10 01:12:49 +00:00
|
|
|
virtual Result<uint64_t> size() const final { return _value->size; }
|
2024-07-28 16:54:04 +00:00
|
|
|
|
2024-08-11 20:37:37 +00:00
|
|
|
Result<char32_t> operator[](uint64_t idx) const {
|
2024-08-10 10:17:20 +00:00
|
|
|
if (idx >= _value->size) return ERROR(IndexOutOfRange);
|
2024-07-28 16:54:04 +00:00
|
|
|
return _value->data[idx];
|
|
|
|
}
|
|
|
|
|
2024-07-19 01:29:30 +00:00
|
|
|
private:
|
2024-07-26 18:32:27 +00:00
|
|
|
GcRoot<PodSymbol> _value;
|
2024-07-19 01:29:30 +00:00
|
|
|
};
|
|
|
|
|
2024-09-05 22:22:45 +00:00
|
|
|
class SrcLoc : public Object {
|
|
|
|
public:
|
|
|
|
SrcLoc() {}
|
|
|
|
SrcLoc(SrcLoc&& rhs) : _value(std::move(rhs._value)) {}
|
|
|
|
SrcLoc(GcRoot<PodSrcLoc>&& val) : _value(std::move(val)) {}
|
|
|
|
static Result<SrcLoc> create(const SourceRange& sourcerange);
|
|
|
|
virtual Tag tag() const final { return Tag::SrcLoc; }
|
|
|
|
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 SrcLoc& rhs) const final;
|
|
|
|
|
|
|
|
virtual void move(Object* obj) final { new (obj) SrcLoc(std::move(_value)); }
|
|
|
|
|
|
|
|
static Result<SrcLoc> create(PodSrcLoc* obj) {
|
|
|
|
return SrcLoc(TRY(MkGcRoot(obj)));
|
|
|
|
}
|
|
|
|
|
2024-09-06 22:32:05 +00:00
|
|
|
static Result<SrcLoc> create(const SourcePosition& start,
|
|
|
|
const SourcePosition& end) {
|
|
|
|
auto pod = TRY(arena_alloc<PodSrcLoc>());
|
|
|
|
pod->header.tag = Tag::SrcLoc;
|
|
|
|
|
|
|
|
pod->sourcerange.start = start;
|
|
|
|
pod->sourcerange.end = end;
|
|
|
|
|
|
|
|
return SrcLoc(TRY(MkGcRoot(pod)));
|
|
|
|
}
|
|
|
|
|
2024-09-05 22:22:45 +00:00
|
|
|
SourceRange sourcerange() const;
|
|
|
|
|
|
|
|
virtual Result<Value> copy_value() const final;
|
|
|
|
Result<SrcLoc> copy() const;
|
|
|
|
|
|
|
|
private:
|
|
|
|
GcRoot<PodSrcLoc> _value;
|
|
|
|
};
|
|
|
|
|
2024-07-19 01:29:30 +00:00
|
|
|
class Syntax : public Object {
|
|
|
|
public:
|
2024-07-26 18:32:27 +00:00
|
|
|
Syntax() {}
|
2024-07-27 18:40:13 +00:00
|
|
|
Syntax(Syntax&& rhs) : _value(std::move(rhs._value)) {}
|
2024-07-26 18:32:27 +00:00
|
|
|
Syntax(GcRoot<PodSyntax>&& val) : _value(std::move(val)) {}
|
2024-09-06 22:32:05 +00:00
|
|
|
static Result<Syntax> create(const String& filename, const SrcLoc& srcloc,
|
|
|
|
const Value& expression);
|
|
|
|
static Result<Syntax> create(const String& filename,
|
|
|
|
const SourcePosition& start,
|
|
|
|
const SourcePosition& end,
|
|
|
|
const Value& expression);
|
2024-08-10 17:46:20 +00:00
|
|
|
virtual Tag tag() const final { return Tag::Syntax; }
|
|
|
|
virtual PodObject* pod() const final { return _value.get(); }
|
|
|
|
virtual Result<short> cmp(const Object& rhs) const final {
|
|
|
|
return -TRY(rhs.cmp(*this));
|
|
|
|
}
|
2024-09-02 23:24:44 +00:00
|
|
|
virtual Result<short> cmp(const Syntax& rhs) const final;
|
2024-07-19 01:29:30 +00:00
|
|
|
|
2024-07-29 23:14:09 +00:00
|
|
|
virtual void move(Object* obj) final { new (obj) Syntax(std::move(_value)); }
|
|
|
|
|
2024-08-09 22:45:06 +00:00
|
|
|
static Result<Syntax> create(PodSyntax* obj) {
|
|
|
|
return Syntax(TRY(MkGcRoot(obj)));
|
2024-07-26 18:32:27 +00:00
|
|
|
}
|
|
|
|
|
2024-09-02 23:24:44 +00:00
|
|
|
Result<Value> filename() const;
|
2024-09-05 22:22:45 +00:00
|
|
|
Result<Value> srcloc() const;
|
2024-09-02 23:24:44 +00:00
|
|
|
Result<Value> expression() const;
|
2024-07-19 01:29:30 +00:00
|
|
|
|
2024-09-07 11:16:55 +00:00
|
|
|
Result<Value> first() const final;
|
|
|
|
Result<Value> second() const final;
|
|
|
|
Result<Value> third() const final;
|
|
|
|
Result<Value> rest() const final;
|
2024-09-11 22:25:17 +00:00
|
|
|
Result<uint64_t> size() const final;
|
2024-09-07 11:16:55 +00:00
|
|
|
|
2024-08-13 00:11:23 +00:00
|
|
|
virtual Result<Value> copy_value() const final;
|
|
|
|
Result<Syntax> copy() const;
|
2024-07-26 18:32:27 +00:00
|
|
|
|
2024-07-19 01:29:30 +00:00
|
|
|
private:
|
2024-07-26 18:32:27 +00:00
|
|
|
GcRoot<PodSyntax> _value;
|
2024-07-19 01:29:30 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
class Pair : public Object {
|
|
|
|
public:
|
2024-07-26 18:32:27 +00:00
|
|
|
Pair() {}
|
2024-07-27 18:40:13 +00:00
|
|
|
Pair(Pair&& rhs) : _value(std::move(rhs._value)) {}
|
2024-07-26 18:32:27 +00:00
|
|
|
Pair(GcRoot<PodPair>&& val) : _value(std::move(val)) {}
|
2024-08-10 17:46:20 +00:00
|
|
|
virtual Tag tag() const final { return Tag::Pair; }
|
|
|
|
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 Pair& rhs) const final { return 0; }
|
2024-07-19 01:29:30 +00:00
|
|
|
|
2024-07-29 23:14:09 +00:00
|
|
|
virtual void move(Object* obj) final { new (obj) Pair(std::move(_value)); }
|
|
|
|
|
2024-08-09 22:45:06 +00:00
|
|
|
static Result<Pair> create(PodPair* obj) { return Pair(TRY(MkGcRoot(obj))); }
|
2024-09-01 22:02:21 +00:00
|
|
|
static Result<Pair> create(const Value& first, const Value& rest);
|
2024-08-28 22:57:01 +00:00
|
|
|
static Result<Pair> create(const Array& arr);
|
2024-07-26 18:32:27 +00:00
|
|
|
|
2024-08-28 22:57:01 +00:00
|
|
|
virtual Result<Value> get(const Value& key) const final;
|
|
|
|
|
|
|
|
Result<Value> first() const final;
|
|
|
|
Result<Value> second() const final;
|
2024-09-01 22:45:20 +00:00
|
|
|
Result<Value> third() const final;
|
2024-08-28 22:57:01 +00:00
|
|
|
Result<Value> rest() const final;
|
2024-07-26 18:32:27 +00:00
|
|
|
|
2024-09-10 02:18:00 +00:00
|
|
|
virtual Result<uint64_t> size() const final;
|
|
|
|
|
2024-08-13 00:11:23 +00:00
|
|
|
virtual Result<Value> copy_value() const final;
|
|
|
|
Result<Pair> copy() const;
|
2024-07-26 18:32:27 +00:00
|
|
|
|
2024-07-19 01:29:30 +00:00
|
|
|
private:
|
2024-07-26 18:32:27 +00:00
|
|
|
GcRoot<PodPair> _value;
|
2024-07-19 01:29:30 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
class Int64 : public Object {
|
|
|
|
public:
|
2024-08-01 17:56:38 +00:00
|
|
|
friend class Float;
|
|
|
|
|
2024-07-27 15:25:44 +00:00
|
|
|
Int64() {}
|
2024-07-27 18:40:13 +00:00
|
|
|
Int64(Int64&& rhs) : _value(std::move(rhs._value)) {}
|
2024-07-27 15:25:44 +00:00
|
|
|
Int64(GcRoot<PodInt64>&& val) : _value(std::move(val)) {}
|
2024-08-10 17:46:20 +00:00
|
|
|
virtual Tag tag() const final { return Tag::Int64; }
|
|
|
|
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 Int64& rhs) const final {
|
2024-08-01 17:56:38 +00:00
|
|
|
return (_value->value > rhs._value->value) -
|
|
|
|
(_value->value < rhs._value->value);
|
|
|
|
}
|
2024-08-10 17:46:20 +00:00
|
|
|
virtual Result<short> cmp(const Float& rhs) const final;
|
2024-07-27 15:25:44 +00:00
|
|
|
|
2024-08-13 00:11:23 +00:00
|
|
|
virtual Result<Value> add(const Object& rhs) const final;
|
|
|
|
virtual Result<Value> add(const Int64& rhs) const final;
|
2024-08-27 19:15:22 +00:00
|
|
|
virtual Result<Value> add(const Float& rhs) const final;
|
2024-08-13 00:11:23 +00:00
|
|
|
|
|
|
|
virtual Result<Value> mul(const Object& rhs) const final;
|
|
|
|
virtual Result<Value> mul(const Int64& rhs) const final;
|
2024-08-27 19:15:22 +00:00
|
|
|
virtual Result<Value> mul(const Float& rhs) const final;
|
2024-08-13 00:11:23 +00:00
|
|
|
|
|
|
|
virtual Result<Value> sub(const Object& rhs) const final;
|
|
|
|
virtual Result<Value> sub_inv(const Int64& rhs) const final;
|
2024-08-27 19:15:22 +00:00
|
|
|
virtual Result<Value> sub_inv(const Float& rhs) const final;
|
2024-08-13 00:11:23 +00:00
|
|
|
|
|
|
|
virtual Result<Value> div(const Object& rhs) const final;
|
|
|
|
virtual Result<Value> div_inv(const Int64& rhs) const final;
|
2024-08-27 19:15:22 +00:00
|
|
|
virtual Result<Value> div_inv(const Float& rhs) const final;
|
2024-08-13 00:11:23 +00:00
|
|
|
|
2024-07-29 23:14:09 +00:00
|
|
|
virtual void move(Object* obj) final { new (obj) Int64(std::move(_value)); }
|
|
|
|
|
2024-08-09 22:45:06 +00:00
|
|
|
static Result<Int64> create(PodInt64* obj) {
|
|
|
|
return Int64(TRY(MkGcRoot(obj)));
|
2024-07-27 15:25:44 +00:00
|
|
|
}
|
|
|
|
|
2024-08-09 22:45:06 +00:00
|
|
|
static Result<Int64> create(double val) {
|
|
|
|
auto pod = TRY(arena_alloc<PodInt64>());
|
2024-07-28 23:14:30 +00:00
|
|
|
pod->header.tag = Tag::Int64;
|
2024-07-27 15:25:44 +00:00
|
|
|
pod->value = val;
|
|
|
|
|
2024-08-09 22:45:06 +00:00
|
|
|
return Int64(TRY(MkGcRoot(pod)));
|
2024-07-27 15:25:44 +00:00
|
|
|
}
|
2024-07-19 01:29:30 +00:00
|
|
|
|
2024-08-11 20:37:37 +00:00
|
|
|
int64_t value() const { return _value->value; }
|
2024-07-19 01:29:30 +00:00
|
|
|
|
2024-08-13 00:11:23 +00:00
|
|
|
virtual Result<Value> copy_value() const final;
|
|
|
|
Result<Int64> copy() const;
|
2024-07-26 18:32:27 +00:00
|
|
|
|
2024-07-19 01:29:30 +00:00
|
|
|
private:
|
2024-07-27 15:25:44 +00:00
|
|
|
GcRoot<PodInt64> _value;
|
2024-07-19 01:29:30 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
class Float : public Object {
|
|
|
|
public:
|
2024-08-01 17:56:38 +00:00
|
|
|
friend class Int64;
|
|
|
|
|
2024-07-27 15:25:44 +00:00
|
|
|
Float() {}
|
2024-07-27 18:40:13 +00:00
|
|
|
Float(Float&& rhs) : _value(std::move(rhs._value)) {}
|
2024-07-27 15:25:44 +00:00
|
|
|
Float(GcRoot<PodFloat>&& val) : _value(std::move(val)) {}
|
2024-08-10 17:46:20 +00:00
|
|
|
virtual Tag tag() const final { return Tag::Float; }
|
|
|
|
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 Float& rhs) const final {
|
2024-08-01 17:56:38 +00:00
|
|
|
return (_value->value > rhs._value->value) -
|
|
|
|
(_value->value < rhs._value->value);
|
|
|
|
}
|
2024-08-10 17:46:20 +00:00
|
|
|
virtual Result<short> cmp(const Int64& rhs) const final;
|
2024-07-27 15:25:44 +00:00
|
|
|
|
2024-08-27 19:15:22 +00:00
|
|
|
virtual Result<Value> add(const Object& rhs) const final;
|
|
|
|
virtual Result<Value> add(const Int64& rhs) const final;
|
|
|
|
virtual Result<Value> add(const Float& rhs) const final;
|
|
|
|
|
|
|
|
virtual Result<Value> mul(const Object& rhs) const final;
|
|
|
|
virtual Result<Value> mul(const Int64& rhs) const final;
|
|
|
|
virtual Result<Value> mul(const Float& rhs) const final;
|
|
|
|
|
|
|
|
virtual Result<Value> sub(const Object& rhs) const final;
|
|
|
|
virtual Result<Value> sub_inv(const Int64& rhs) const final;
|
|
|
|
virtual Result<Value> sub_inv(const Float& rhs) const final;
|
|
|
|
|
|
|
|
virtual Result<Value> div(const Object& rhs) const final;
|
|
|
|
virtual Result<Value> div_inv(const Int64& rhs) const final;
|
|
|
|
virtual Result<Value> div_inv(const Float& rhs) const final;
|
|
|
|
|
2024-07-29 23:14:09 +00:00
|
|
|
virtual void move(Object* obj) final { new (obj) Float(std::move(_value)); }
|
|
|
|
|
2024-08-09 22:45:06 +00:00
|
|
|
static Result<Float> create(PodFloat* obj) {
|
|
|
|
return Float(TRY(MkGcRoot(obj)));
|
2024-07-27 15:25:44 +00:00
|
|
|
}
|
|
|
|
|
2024-08-09 22:45:06 +00:00
|
|
|
static Result<Float> create(double val) {
|
|
|
|
auto pod = TRY(arena_alloc<PodFloat>());
|
2024-07-28 23:14:30 +00:00
|
|
|
pod->header.tag = Tag::Float;
|
2024-07-27 15:25:44 +00:00
|
|
|
pod->value = val;
|
|
|
|
|
2024-08-09 22:45:06 +00:00
|
|
|
return Float(TRY(MkGcRoot(pod)));
|
2024-07-27 15:25:44 +00:00
|
|
|
}
|
2024-07-19 01:29:30 +00:00
|
|
|
|
2024-08-11 20:37:37 +00:00
|
|
|
double value() const { return _value->value; }
|
2024-07-19 01:29:30 +00:00
|
|
|
|
2024-08-13 00:11:23 +00:00
|
|
|
virtual Result<Value> copy_value() const final;
|
|
|
|
Result<Float> copy() const;
|
2024-07-26 18:32:27 +00:00
|
|
|
|
2024-07-19 01:29:30 +00:00
|
|
|
private:
|
2024-07-27 15:25:44 +00:00
|
|
|
GcRoot<PodFloat> _value;
|
2024-07-19 01:29:30 +00:00
|
|
|
};
|
|
|
|
|
2024-07-27 18:40:13 +00:00
|
|
|
class Bool : public Object {
|
|
|
|
public:
|
|
|
|
Bool() {}
|
|
|
|
Bool(Bool&& rhs) : _value(std::move(rhs._value)) {}
|
|
|
|
Bool(GcRoot<PodBool>&& val) : _value(std::move(val)) {}
|
|
|
|
|
2024-08-10 17:46:20 +00:00
|
|
|
virtual Tag tag() const final { return Tag::Bool; }
|
|
|
|
virtual PodObject* pod() const final { return _value.get(); }
|
|
|
|
virtual Result<short> cmp(const Object& rhs) const final {
|
|
|
|
return -TRY(rhs.cmp(*this));
|
|
|
|
}
|
2024-08-15 00:18:05 +00:00
|
|
|
virtual Result<short> cmp(const Bool& rhs) const final {
|
|
|
|
return (_value->value > rhs._value->value) -
|
|
|
|
(_value->value < rhs._value->value);
|
|
|
|
}
|
2024-07-27 18:40:13 +00:00
|
|
|
|
2024-07-29 23:14:09 +00:00
|
|
|
virtual void move(Object* obj) final { new (obj) Bool(std::move(_value)); }
|
|
|
|
|
2024-08-09 22:45:06 +00:00
|
|
|
static Result<Bool> create(PodBool* obj) { return Bool(TRY(MkGcRoot(obj))); }
|
2024-07-27 18:40:13 +00:00
|
|
|
|
2024-08-09 22:45:06 +00:00
|
|
|
static Result<Bool> create(bool val) {
|
|
|
|
auto pod = TRY(arena_alloc<PodBool>());
|
2024-07-28 23:14:30 +00:00
|
|
|
pod->header.tag = Tag::Bool;
|
2024-07-27 18:40:13 +00:00
|
|
|
pod->value = val;
|
|
|
|
|
2024-08-09 22:45:06 +00:00
|
|
|
return Bool(TRY(MkGcRoot(pod)));
|
2024-07-27 18:40:13 +00:00
|
|
|
}
|
|
|
|
|
2024-08-11 20:37:37 +00:00
|
|
|
bool value() const { return _value->value; }
|
2024-07-27 18:40:13 +00:00
|
|
|
|
2024-08-13 00:11:23 +00:00
|
|
|
virtual Result<Value> copy_value() const final;
|
|
|
|
Result<Bool> copy() const;
|
2024-07-27 18:40:13 +00:00
|
|
|
|
|
|
|
private:
|
|
|
|
GcRoot<PodBool> _value;
|
|
|
|
};
|
|
|
|
|
2024-08-10 17:24:16 +00:00
|
|
|
class Opcode : public Object {
|
|
|
|
public:
|
|
|
|
Opcode() {}
|
|
|
|
Opcode(Opcode&& rhs) : _value(std::move(rhs._value)) {}
|
|
|
|
Opcode(GcRoot<PodOpcode>&& val) : _value(std::move(val)) {}
|
|
|
|
|
2024-08-10 17:46:20 +00:00
|
|
|
virtual Tag tag() const final { return Tag::Opcode; }
|
|
|
|
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; }
|
2024-08-10 17:24:16 +00:00
|
|
|
|
|
|
|
virtual void move(Object* obj) final { new (obj) Opcode(std::move(_value)); }
|
|
|
|
|
|
|
|
static Result<Opcode> create(PodOpcode* obj) {
|
|
|
|
return Opcode(TRY(MkGcRoot(obj)));
|
|
|
|
}
|
|
|
|
|
|
|
|
static Result<Opcode> create(Oc opcode, OpArg arg1 = {0, 0},
|
|
|
|
OpArg arg2 = {0, 0}, OpArg arg3 = {0, 0},
|
|
|
|
OpArg arg4 = {0, 0}) {
|
|
|
|
auto pod = TRY(arena_alloc<PodOpcode>());
|
|
|
|
pod->header.tag = Tag::Opcode;
|
|
|
|
pod->opcode = opcode;
|
|
|
|
pod->arg1 = arg1;
|
|
|
|
pod->arg2 = arg2;
|
|
|
|
pod->arg3 = arg3;
|
|
|
|
pod->arg4 = arg4;
|
|
|
|
|
|
|
|
return Opcode(TRY(MkGcRoot(pod)));
|
|
|
|
}
|
|
|
|
|
2024-08-11 20:37:37 +00:00
|
|
|
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; }
|
2024-08-10 17:24:16 +00:00
|
|
|
|
2024-08-13 00:11:23 +00:00
|
|
|
virtual Result<Value> copy_value() const final;
|
|
|
|
Result<Opcode> copy() const;
|
2024-08-10 17:24:16 +00:00
|
|
|
|
|
|
|
private:
|
|
|
|
GcRoot<PodOpcode> _value;
|
|
|
|
};
|
2024-08-11 20:37:37 +00:00
|
|
|
|
|
|
|
class Function : public Object {
|
|
|
|
public:
|
|
|
|
Function() {}
|
|
|
|
Function(Function&& rhs) : _value(std::move(rhs._value)) {}
|
|
|
|
Function(GcRoot<PodFunction>&& val) : _value(std::move(val)) {}
|
|
|
|
|
2024-08-12 22:05:40 +00:00
|
|
|
Function& operator=(Function&& rhs) {
|
|
|
|
_value = std::move(rhs._value);
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
2024-08-11 20:37:37 +00:00
|
|
|
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));
|
|
|
|
}
|
2024-08-17 22:22:21 +00:00
|
|
|
virtual Result<short> cmp(const Function& rhs) const final;
|
2024-08-11 20:37:37 +00:00
|
|
|
|
|
|
|
virtual void move(Object* obj) final {
|
|
|
|
new (obj) Function(std::move(_value));
|
|
|
|
}
|
|
|
|
|
|
|
|
static Result<Function> create(PodFunction* obj) {
|
|
|
|
return Function(TRY(MkGcRoot(obj)));
|
|
|
|
}
|
|
|
|
|
2024-08-21 22:45:19 +00:00
|
|
|
static Result<Function> create(const Function& prototype,
|
|
|
|
const Array& closure);
|
|
|
|
|
2024-08-11 20:37:37 +00:00
|
|
|
static Result<Function> create(const Value& name, uint64_t arity,
|
2024-08-21 22:45:19 +00:00
|
|
|
const Array& constants, const Array& code,
|
|
|
|
const Array& closure);
|
2024-08-11 20:37:37 +00:00
|
|
|
|
2024-08-17 22:22:21 +00:00
|
|
|
uint64_t arity() const { return _value->arity; }
|
2024-08-11 20:37:37 +00:00
|
|
|
|
|
|
|
Result<Value> name() const;
|
2024-08-13 00:11:23 +00:00
|
|
|
Result<Array> code() const;
|
|
|
|
Result<Array> constants() const;
|
2024-08-21 22:45:19 +00:00
|
|
|
Result<Array> closure() const;
|
2024-08-11 20:37:37 +00:00
|
|
|
|
2024-08-13 00:11:23 +00:00
|
|
|
virtual Result<Value> copy_value() const final;
|
|
|
|
Result<Function> copy() const;
|
2024-08-11 20:37:37 +00:00
|
|
|
|
|
|
|
private:
|
|
|
|
GcRoot<PodFunction> _value;
|
|
|
|
};
|
|
|
|
|
2024-08-24 23:55:11 +00:00
|
|
|
class StdlibFunction : public Object {
|
|
|
|
public:
|
|
|
|
StdlibFunction() {}
|
|
|
|
StdlibFunction(StdlibFunction&& rhs) : _value(std::move(rhs._value)) {}
|
|
|
|
StdlibFunction(GcRoot<PodStdlibFunction>&& val) : _value(std::move(val)) {}
|
|
|
|
|
|
|
|
StdlibFunction& operator=(StdlibFunction&& rhs) {
|
|
|
|
_value = std::move(rhs._value);
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
virtual Tag tag() const final { return Tag::StdlibFunction; }
|
|
|
|
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 StdlibFunction& rhs) const final;
|
|
|
|
|
|
|
|
virtual void move(Object* obj) final {
|
|
|
|
new (obj) StdlibFunction(std::move(_value));
|
|
|
|
}
|
|
|
|
|
|
|
|
static Result<StdlibFunction> create(PodStdlibFunction* obj) {
|
|
|
|
return StdlibFunction(TRY(MkGcRoot(obj)));
|
|
|
|
}
|
|
|
|
|
|
|
|
static Result<StdlibFunction> create(StdlibFunctionId fun_id);
|
|
|
|
|
|
|
|
Result<Symbol> name() const;
|
|
|
|
StdlibFunctionId fun_id() const;
|
|
|
|
|
|
|
|
virtual Result<Value> copy_value() const final;
|
|
|
|
Result<StdlibFunction> copy() const;
|
|
|
|
|
|
|
|
private:
|
|
|
|
GcRoot<PodStdlibFunction> _value;
|
|
|
|
};
|
|
|
|
|
2024-08-23 23:28:29 +00:00
|
|
|
class Module : public Object {
|
|
|
|
public:
|
|
|
|
Module() {}
|
|
|
|
Module(Module&& rhs) : _value(std::move(rhs._value)) {}
|
|
|
|
Module(GcRoot<PodModule>&& val) : _value(std::move(val)) {}
|
|
|
|
|
|
|
|
Module& operator=(Module&& rhs) {
|
|
|
|
_value = std::move(rhs._value);
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
virtual Tag tag() const final { return Tag::Module; }
|
|
|
|
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 Module& rhs) const final;
|
|
|
|
|
|
|
|
virtual void move(Object* obj) final { new (obj) Module(std::move(_value)); }
|
|
|
|
|
|
|
|
static Result<Module> create(PodModule* obj) {
|
|
|
|
return Module(TRY(MkGcRoot(obj)));
|
|
|
|
}
|
|
|
|
|
2024-09-01 13:31:25 +00:00
|
|
|
static Result<Module> create(const Value& name, const Function& fun);
|
2024-08-23 23:28:29 +00:00
|
|
|
|
|
|
|
Result<Value> name() const;
|
|
|
|
Result<Function> fun() const;
|
|
|
|
|
|
|
|
virtual Result<Value> copy_value() const final;
|
|
|
|
Result<Module> copy() const;
|
|
|
|
|
|
|
|
private:
|
|
|
|
GcRoot<PodModule> _value;
|
|
|
|
};
|
|
|
|
|
2024-09-12 21:43:38 +00:00
|
|
|
class StackFrame : public Object {
|
2024-08-12 22:05:40 +00:00
|
|
|
public:
|
2024-09-12 21:43:38 +00:00
|
|
|
StackFrame() {}
|
|
|
|
StackFrame(StackFrame&& rhs) : _value(std::move(rhs._value)) {}
|
|
|
|
StackFrame(GcRoot<PodStackFrame>&& val) : _value(std::move(val)) {}
|
2024-08-12 22:05:40 +00:00
|
|
|
|
2024-09-12 23:54:32 +00:00
|
|
|
StackFrame& operator=(StackFrame&& rhs) {
|
|
|
|
_value = std::move(rhs._value);
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
2024-09-12 21:43:38 +00:00
|
|
|
virtual Tag tag() const final { return Tag::StackFrame; }
|
2024-08-12 22:05:40 +00:00
|
|
|
virtual PodObject* pod() const final { return _value.get(); }
|
|
|
|
virtual Result<short> cmp(const Object& rhs) const final {
|
|
|
|
return -TRY(rhs.cmp(*this));
|
|
|
|
}
|
2024-09-12 21:43:38 +00:00
|
|
|
virtual Result<short> cmp(const StackFrame& rhs) const final { return 0; }
|
2024-08-12 22:05:40 +00:00
|
|
|
|
2024-09-12 21:43:38 +00:00
|
|
|
virtual void move(Object* obj) final {
|
|
|
|
new (obj) StackFrame(std::move(_value));
|
|
|
|
}
|
2024-08-12 22:05:40 +00:00
|
|
|
|
2024-09-12 21:43:38 +00:00
|
|
|
static Result<StackFrame> create(PodStackFrame* obj) {
|
|
|
|
return StackFrame(TRY(MkGcRoot(obj)));
|
2024-08-12 22:05:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
using Object::get;
|
|
|
|
Result<Value> get(uint64_t idx) const;
|
2024-09-12 23:54:32 +00:00
|
|
|
Result<StackFrame> set(uint64_t idx, const Value& val);
|
|
|
|
Result<StackFrame> settop(uint64_t idx);
|
|
|
|
Result<Value> parent() const;
|
|
|
|
Result<Function> fun() const;
|
2024-09-13 20:15:57 +00:00
|
|
|
uint64_t pc() const;
|
|
|
|
Result<StackFrame> setpc(uint64_t pc);
|
|
|
|
Result<StackFrame> incpc();
|
2024-09-12 23:54:32 +00:00
|
|
|
Result<uint64_t> size() const { return _value->size; }
|
2024-08-12 22:05:40 +00:00
|
|
|
|
2024-09-13 20:15:57 +00:00
|
|
|
static Result<StackFrame> create(const Value& parent, const Function& fun);
|
2024-08-12 22:05:40 +00:00
|
|
|
|
2024-08-21 22:45:19 +00:00
|
|
|
Result<Array> slice(uint64_t start, uint64_t end) {
|
2024-09-12 23:54:32 +00:00
|
|
|
if (start > end || end > _value->size) return ERROR(IndexOutOfRange);
|
2024-08-21 22:45:19 +00:00
|
|
|
uint64_t res_size = end - start;
|
|
|
|
auto pod = TRY(arena_alloc<PodArray>(res_size * sizeof(PodObject*)));
|
2024-09-01 15:13:28 +00:00
|
|
|
pod->header.tag = Tag::Array;
|
2024-08-21 22:45:19 +00:00
|
|
|
pod->size = res_size;
|
|
|
|
for (uint64_t i = 0; i < end - start; i++) {
|
|
|
|
pod->data[i] = _value->data[start + i];
|
|
|
|
}
|
|
|
|
|
|
|
|
return Array(TRY(MkGcRoot(pod)));
|
|
|
|
}
|
|
|
|
|
2024-08-13 00:11:23 +00:00
|
|
|
virtual Result<Value> copy_value() const final;
|
2024-09-12 21:43:38 +00:00
|
|
|
Result<StackFrame> copy() const;
|
2024-08-12 22:05:40 +00:00
|
|
|
|
|
|
|
private:
|
2024-09-12 21:43:38 +00:00
|
|
|
GcRoot<PodStackFrame> _value;
|
2024-08-12 22:05:40 +00:00
|
|
|
};
|
|
|
|
|
2024-09-07 16:37:12 +00:00
|
|
|
class Error : public Object {
|
|
|
|
public:
|
|
|
|
Error() {}
|
|
|
|
Error(Error&& rhs) : _value(std::move(rhs._value)) {}
|
|
|
|
Error(GcRoot<PodError>&& val) : _value(std::move(val)) {}
|
|
|
|
|
|
|
|
virtual Tag tag() const final { return Tag::Error; }
|
|
|
|
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 Error& rhs) const final;
|
|
|
|
|
|
|
|
virtual void move(Object* obj) final { new (obj) Error(std::move(_value)); }
|
|
|
|
|
|
|
|
static Result<Error> create(PodError* obj) {
|
|
|
|
return Error(TRY(MkGcRoot(obj)));
|
|
|
|
}
|
|
|
|
|
|
|
|
static Result<Error> create(const char* name, const char* message) {
|
|
|
|
auto name_str = TRY(Symbol::create(name));
|
|
|
|
auto message_str = TRY(String::create(message));
|
|
|
|
|
|
|
|
auto pod = TRY(arena_alloc<PodError>());
|
|
|
|
pod->header.tag = Tag::Error;
|
|
|
|
|
|
|
|
pod->name = name_str.pod();
|
|
|
|
pod->message = message_str.pod();
|
|
|
|
|
|
|
|
return Error(TRY(MkGcRoot(pod)));
|
|
|
|
}
|
|
|
|
|
2024-09-08 01:31:54 +00:00
|
|
|
static Result<Error> create(const Symbol& name, const String& message) {
|
|
|
|
auto pod = TRY(arena_alloc<PodError>());
|
|
|
|
pod->header.tag = Tag::Error;
|
|
|
|
|
|
|
|
pod->name = name.pod();
|
|
|
|
pod->message = message.pod();
|
|
|
|
|
|
|
|
return Error(TRY(MkGcRoot(pod)));
|
|
|
|
}
|
|
|
|
|
2024-09-07 16:37:12 +00:00
|
|
|
Result<Value> name() const;
|
|
|
|
Result<Value> message() const;
|
|
|
|
|
|
|
|
virtual Result<Value> copy_value() const final;
|
|
|
|
Result<Error> copy() const;
|
|
|
|
|
|
|
|
private:
|
|
|
|
GcRoot<PodError> _value;
|
|
|
|
};
|
|
|
|
|
2024-07-19 01:29:30 +00:00
|
|
|
// note: this class doesn't perform proper destruction of objects in some cases
|
|
|
|
class Value {
|
|
|
|
public:
|
|
|
|
Value() { new (buf) Nil(); }
|
|
|
|
~Value() { ((Object*)buf)->~Object(); }
|
2024-07-27 00:01:38 +00:00
|
|
|
Value(Value&& val) {
|
2024-07-29 23:14:09 +00:00
|
|
|
((Object*)val.buf)->move((Object*)buf);
|
2024-07-27 00:01:38 +00:00
|
|
|
new (val.buf) Nil();
|
|
|
|
}
|
2024-07-26 18:32:27 +00:00
|
|
|
Value(const Value&) = delete;
|
2024-07-19 01:29:30 +00:00
|
|
|
|
|
|
|
template <class T>
|
2024-07-26 18:32:27 +00:00
|
|
|
Value(T&& obj)
|
|
|
|
requires std::derived_from<T, Object>
|
2024-07-19 01:29:30 +00:00
|
|
|
{
|
2024-07-26 18:32:27 +00:00
|
|
|
new (buf) T(std::move(obj));
|
2024-07-19 01:29:30 +00:00
|
|
|
}
|
|
|
|
|
2024-07-27 15:25:44 +00:00
|
|
|
Value& operator=(Value&& val) {
|
2024-07-28 22:37:43 +00:00
|
|
|
((Object*)buf)->~Object();
|
2024-07-29 23:14:09 +00:00
|
|
|
((Object*)val.buf)->move((Object*)buf);
|
2024-07-27 15:25:44 +00:00
|
|
|
new (val.buf) Nil();
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
2024-08-09 22:45:06 +00:00
|
|
|
static Result<Value> create(PodObject* obj);
|
2024-07-26 19:20:13 +00:00
|
|
|
|
2024-08-09 22:45:06 +00:00
|
|
|
static Result<Value> create(const int64_t& value) {
|
|
|
|
return Value(TRY(Int64::create(value)));
|
2024-08-01 21:45:16 +00:00
|
|
|
}
|
|
|
|
|
2024-08-09 22:45:06 +00:00
|
|
|
static Result<Value> create(const char* value) {
|
|
|
|
return Value(TRY(String::create(value)));
|
2024-08-02 22:27:36 +00:00
|
|
|
}
|
|
|
|
|
2024-07-19 01:29:30 +00:00
|
|
|
template <class T>
|
2024-08-10 17:56:42 +00:00
|
|
|
bool is() const {
|
2024-07-19 01:29:30 +00:00
|
|
|
return dynamic_cast<T*>((Object*)buf) != nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class T>
|
2024-08-10 17:56:42 +00:00
|
|
|
T* to() const {
|
2024-07-19 01:29:30 +00:00
|
|
|
return dynamic_cast<T*>((Object*)buf);
|
|
|
|
}
|
|
|
|
|
2024-08-10 17:46:20 +00:00
|
|
|
PodObject* pod() const { return ((Object*)buf)->pod(); }
|
2024-08-11 20:37:37 +00:00
|
|
|
Tag tag() const { return ((Object*)buf)->tag(); }
|
2024-07-27 15:25:44 +00:00
|
|
|
|
2024-07-19 01:29:30 +00:00
|
|
|
Object& operator*() { return *(Object*)(buf); }
|
|
|
|
Object* operator->() { return (Object*)(buf); }
|
|
|
|
|
2024-08-10 17:46:20 +00:00
|
|
|
Result<short> cmp(const Value& rhs) const {
|
2024-08-09 22:45:06 +00:00
|
|
|
return ((Object*)buf)->cmp(*(Object*)rhs.buf);
|
2024-08-01 17:56:38 +00:00
|
|
|
}
|
|
|
|
|
2024-08-13 00:11:23 +00:00
|
|
|
Result<Value> add(const Value& rhs) const {
|
|
|
|
return ((Object*)buf)->add(*(Object*)rhs.buf);
|
|
|
|
}
|
|
|
|
|
|
|
|
Result<Value> mul(const Value& rhs) const {
|
|
|
|
return ((Object*)buf)->mul(*(Object*)rhs.buf);
|
|
|
|
}
|
|
|
|
|
|
|
|
Result<Value> sub(const Value& rhs) const {
|
|
|
|
return ((Object*)buf)->sub(*(Object*)rhs.buf);
|
|
|
|
}
|
|
|
|
|
|
|
|
Result<Value> div(const Value& rhs) const {
|
|
|
|
return ((Object*)buf)->div(*(Object*)rhs.buf);
|
|
|
|
}
|
|
|
|
|
2024-08-09 22:45:06 +00:00
|
|
|
Result<Value> get(Value& key) { return ((Object*)buf)->get(key); }
|
|
|
|
Result<Value> get(int64_t key) {
|
|
|
|
Value k = TRY(Int64::create(key));
|
|
|
|
return ((Object*)buf)->get(k);
|
2024-08-03 17:53:14 +00:00
|
|
|
}
|
2024-08-29 22:14:33 +00:00
|
|
|
Result<Value> first() const { return ((Object*)buf)->first(); }
|
|
|
|
Result<Value> second() const { return ((Object*)buf)->second(); }
|
2024-09-01 22:45:20 +00:00
|
|
|
Result<Value> third() const { return ((Object*)buf)->third(); }
|
2024-08-29 22:14:33 +00:00
|
|
|
Result<Value> rest() const { return ((Object*)buf)->rest(); }
|
2024-09-10 02:18:00 +00:00
|
|
|
Result<uint64_t> size() const { return ((Object*)buf)->size(); }
|
2024-08-03 17:53:14 +00:00
|
|
|
|
2024-08-03 12:43:59 +00:00
|
|
|
// TODO: cmp() probably doesn't need arena parameter
|
|
|
|
// Result<bool> operator==(Value& rhs) { return TRY(cmp(rhs)) == 0; }
|
|
|
|
// Result<bool> operator!=(Value& rhs) { return TRY(cmp(rhs)) != 0; }
|
2024-08-01 17:56:38 +00:00
|
|
|
|
2024-08-13 00:11:23 +00:00
|
|
|
Result<Value> copy() const { return ((Object*)buf)->copy_value(); }
|
2024-07-26 18:32:27 +00:00
|
|
|
|
2024-07-19 01:29:30 +00:00
|
|
|
private:
|
2024-07-26 18:32:27 +00:00
|
|
|
uint8_t buf[24];
|
2024-07-19 01:29:30 +00:00
|
|
|
};
|
|
|
|
|
2024-07-26 18:32:27 +00:00
|
|
|
Result<Value> syntax_unwrap(Value& val);
|
2024-07-27 15:25:44 +00:00
|
|
|
|
2024-08-09 22:45:06 +00:00
|
|
|
Result<Value> reverse(Value& val);
|
2024-07-28 22:37:43 +00:00
|
|
|
|
2024-08-11 20:37:37 +00:00
|
|
|
Result<void> debug_print(const String& val);
|
|
|
|
Result<void> debug_print(const Value& val);
|
2024-09-08 01:31:54 +00:00
|
|
|
Result<void> debug_print(const char* val);
|
2024-08-01 21:45:16 +00:00
|
|
|
|
2024-08-31 16:30:10 +00:00
|
|
|
template <class T>
|
|
|
|
Result<void> debug_print(const T& val)
|
|
|
|
requires std::derived_from<T, Object>
|
|
|
|
{
|
|
|
|
return debug_print(TRY(val.copy_value()));
|
|
|
|
}
|
|
|
|
|
2024-08-01 21:45:16 +00:00
|
|
|
template <class K, class V>
|
2024-08-09 22:45:06 +00:00
|
|
|
Result<Dict> Dict::insert(const K& key, const V& value) {
|
|
|
|
Value k = TRY(Value::create(key));
|
|
|
|
Value v = TRY(Value::create(value));
|
2024-08-01 21:45:16 +00:00
|
|
|
|
2024-08-09 22:45:06 +00:00
|
|
|
return insert(k, v);
|
2024-08-01 21:45:16 +00:00
|
|
|
}
|
2024-08-03 23:33:17 +00:00
|
|
|
|
|
|
|
template <class V>
|
2024-08-10 17:56:42 +00:00
|
|
|
Result<Array> Array::append(const V& value) const {
|
2024-08-09 22:45:06 +00:00
|
|
|
Value v = TRY(Value::create(value));
|
|
|
|
return append(v);
|
2024-08-03 23:33:17 +00:00
|
|
|
}
|
2024-09-07 09:45:43 +00:00
|
|
|
|
|
|
|
Result<bool> syntax_is_list(const Value& value);
|
|
|
|
Result<bool> syntax_is_nil(const Value& value);
|
|
|
|
Result<Value> syntax_unwrap(const Value& value);
|
2024-09-07 19:31:39 +00:00
|
|
|
Result<Value> syntax_unwrap_all(const Value& value);
|
2024-09-07 23:52:20 +00:00
|
|
|
|
|
|
|
Result<String> build_string(const Value& value);
|
2024-09-08 01:31:54 +00:00
|
|
|
Result<String> build_string(const String& value);
|
2024-09-07 23:52:20 +00:00
|
|
|
Result<String> build_string(const char* value);
|
2024-09-08 01:31:54 +00:00
|
|
|
Result<String> build_string(int64_t value);
|
|
|
|
Result<String> build_string(uint64_t value);
|
2024-09-07 23:52:20 +00:00
|
|
|
|
|
|
|
template <class T, class... Args>
|
|
|
|
Result<String> build_string(const T& value, Args&&... args) {
|
|
|
|
auto first = TRY(build_string(value));
|
|
|
|
auto rest = TRY(build_string(std::forward<Args>(args)...));
|
|
|
|
|
|
|
|
first = TRY(first.concat(rest));
|
|
|
|
return first;
|
|
|
|
}
|
2024-09-11 00:35:38 +00:00
|
|
|
|
|
|
|
Result<void> print_string(const String& s);
|