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"
|
|
|
|
#include "pod.hpp"
|
|
|
|
|
|
|
|
// Forward declarations
|
|
|
|
|
|
|
|
class Value;
|
|
|
|
|
|
|
|
struct SourcePosition {
|
|
|
|
size_t line{1};
|
|
|
|
size_t column{1};
|
|
|
|
size_t offset{0};
|
|
|
|
};
|
|
|
|
|
|
|
|
struct SourceRange {
|
|
|
|
SourcePosition start;
|
|
|
|
SourcePosition end;
|
|
|
|
};
|
|
|
|
|
|
|
|
class PodInt64 final : public PodObject {
|
|
|
|
public:
|
|
|
|
PodInt64() : PodObject(Tag::Int64){};
|
|
|
|
|
|
|
|
int64_t value;
|
|
|
|
};
|
|
|
|
|
|
|
|
class PodFloat final : public PodObject {
|
|
|
|
public:
|
|
|
|
PodFloat() : PodObject(Tag::Float){};
|
|
|
|
|
|
|
|
double value;
|
|
|
|
};
|
|
|
|
|
|
|
|
class PodString final : public PodObject {
|
|
|
|
public:
|
|
|
|
PodString() : PodObject(Tag::String){};
|
|
|
|
|
|
|
|
uint64_t size;
|
|
|
|
char32_t data[];
|
|
|
|
};
|
|
|
|
|
|
|
|
class PodSymbol final : public PodObject {
|
|
|
|
public:
|
|
|
|
PodSymbol() : PodObject(Tag::Symbol){};
|
|
|
|
|
|
|
|
uint64_t size;
|
|
|
|
char32_t data[];
|
|
|
|
};
|
|
|
|
|
|
|
|
class PodSyntax : public PodObject {
|
|
|
|
public:
|
|
|
|
PodSyntax() : PodObject(Tag::Syntax){};
|
|
|
|
OffPtr<PodString> filename;
|
|
|
|
OffPtr<PodString> modulename;
|
|
|
|
OffPtr<PodObject> expression;
|
|
|
|
SourceRange sourcerange;
|
|
|
|
};
|
|
|
|
|
|
|
|
class PodPair : public PodObject {
|
|
|
|
public:
|
|
|
|
PodPair() : PodObject(Tag::Pair){};
|
|
|
|
OffPtr<PodObject> first;
|
|
|
|
OffPtr<PodObject> second;
|
|
|
|
};
|
|
|
|
|
|
|
|
class Object {
|
|
|
|
public:
|
|
|
|
virtual Tag tag() = 0;
|
2024-07-26 18:32:27 +00:00
|
|
|
virtual Result<Value> copy(Arena& arena) = 0;
|
2024-07-19 01:29:30 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
class Nil : public Object {
|
|
|
|
public:
|
|
|
|
Nil() {}
|
|
|
|
|
|
|
|
virtual Tag tag() final { return Tag::Nil; }
|
2024-07-26 18:32:27 +00:00
|
|
|
virtual Result<Value> copy(Arena& arena) final;
|
2024-07-19 01:29:30 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
class String : public Object {
|
|
|
|
public:
|
2024-07-26 18:32:27 +00:00
|
|
|
String() {}
|
|
|
|
String(GcRoot<PodString>&& val) : _value(std::move(val)) {}
|
2024-07-19 01:29:30 +00:00
|
|
|
virtual Tag tag() final { return Tag::String; }
|
|
|
|
|
2024-07-26 18:32:27 +00:00
|
|
|
static Result<String> create(Arena& arena, PodString* obj) {
|
|
|
|
return String(TRY(MkGcRoot(obj, arena)));
|
|
|
|
}
|
2024-07-20 21:42:49 +00:00
|
|
|
static Result<String> create(Arena& arena, char32_t* chars, int64_t size) {
|
|
|
|
auto pod_string = TRY(arena.alloc<PodString>(size * sizeof(char32_t)));
|
|
|
|
|
|
|
|
memcpy(pod_string->data, chars, size * sizeof(char32_t));
|
|
|
|
|
2024-07-26 18:32:27 +00:00
|
|
|
return String(TRY(MkGcRoot(pod_string, arena)));
|
2024-07-20 21:42:49 +00:00
|
|
|
}
|
|
|
|
|
2024-07-26 18:32:27 +00:00
|
|
|
virtual Result<Value> copy(Arena& arena) final;
|
|
|
|
|
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-07-26 18:32:27 +00:00
|
|
|
Symbol() {}
|
|
|
|
Symbol(GcRoot<PodSymbol>&& val) : _value(std::move(val)) {}
|
2024-07-19 01:29:30 +00:00
|
|
|
virtual Tag tag() final { return Tag::Symbol; }
|
|
|
|
|
2024-07-26 18:32:27 +00:00
|
|
|
static Result<Symbol> create(Arena& arena, PodSymbol* obj) {
|
|
|
|
return Symbol(TRY(MkGcRoot(obj, arena)));
|
|
|
|
}
|
|
|
|
|
2024-07-20 21:42:49 +00:00
|
|
|
static Result<Symbol> create(Arena& arena, char32_t* chars, int64_t size) {
|
|
|
|
auto pod_symbol = TRY(arena.alloc<PodSymbol>(size * sizeof(char32_t)));
|
|
|
|
|
|
|
|
memcpy(pod_symbol->data, chars, size * sizeof(char32_t));
|
|
|
|
|
2024-07-26 18:32:27 +00:00
|
|
|
return Symbol(TRY(MkGcRoot(pod_symbol, arena)));
|
2024-07-20 21:42:49 +00:00
|
|
|
}
|
|
|
|
|
2024-07-26 18:32:27 +00:00
|
|
|
virtual Result<Value> copy(Arena& arena) final;
|
|
|
|
|
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
|
|
|
};
|
|
|
|
|
|
|
|
class Syntax : public Object {
|
|
|
|
public:
|
2024-07-26 18:32:27 +00:00
|
|
|
Syntax() {}
|
|
|
|
Syntax(GcRoot<PodSyntax>&& val) : _value(std::move(val)) {}
|
2024-07-19 01:29:30 +00:00
|
|
|
Syntax(String filename, String modulename, Value expression);
|
|
|
|
virtual Tag tag() final { return Tag::Syntax; }
|
|
|
|
|
2024-07-26 18:32:27 +00:00
|
|
|
static Result<Syntax> create(Arena& arena, PodSyntax* obj) {
|
|
|
|
return Syntax(TRY(MkGcRoot(obj, arena)));
|
|
|
|
}
|
|
|
|
|
2024-07-19 01:29:30 +00:00
|
|
|
Value get_value();
|
|
|
|
|
2024-07-26 18:32:27 +00:00
|
|
|
virtual Result<Value> copy(Arena& arena) final;
|
|
|
|
|
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() {}
|
|
|
|
Pair(GcRoot<PodPair>&& val) : _value(std::move(val)) {}
|
2024-07-19 01:29:30 +00:00
|
|
|
virtual Tag tag() final { return Tag::Pair; }
|
|
|
|
|
2024-07-26 18:32:27 +00:00
|
|
|
static Result<Pair> create(Arena& arena, PodPair* obj) {
|
|
|
|
return Pair(TRY(MkGcRoot(obj, arena)));
|
|
|
|
}
|
|
|
|
|
|
|
|
static Result<Value> first(Arena& arena);
|
|
|
|
|
|
|
|
virtual Result<Value> copy(Arena& arena) final;
|
|
|
|
|
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:
|
|
|
|
Int64() : _value(0) {}
|
|
|
|
Int64(int64_t val) : _value(val) {}
|
|
|
|
virtual ~Int64() = default;
|
|
|
|
|
|
|
|
virtual Tag tag() final { return Tag::Int64; }
|
|
|
|
|
|
|
|
int64_t value() { return _value; }
|
|
|
|
|
2024-07-26 18:32:27 +00:00
|
|
|
virtual Result<Value> copy(Arena& arena) final;
|
|
|
|
|
2024-07-19 01:29:30 +00:00
|
|
|
private:
|
|
|
|
int64_t _value;
|
|
|
|
};
|
|
|
|
|
|
|
|
class Float : public Object {
|
|
|
|
public:
|
|
|
|
Float() : _value(0) {}
|
2024-07-26 18:32:27 +00:00
|
|
|
Float(double val) : _value(val) {}
|
2024-07-19 01:29:30 +00:00
|
|
|
virtual ~Float() = default;
|
|
|
|
|
|
|
|
virtual Tag tag() final { return Tag::Float; }
|
|
|
|
|
|
|
|
double value() { return _value; }
|
|
|
|
|
2024-07-26 18:32:27 +00:00
|
|
|
virtual Result<Value> copy(Arena& arena) final;
|
|
|
|
|
2024-07-19 01:29:30 +00:00
|
|
|
private:
|
|
|
|
double _value;
|
|
|
|
};
|
|
|
|
|
|
|
|
// 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-26 18:32:27 +00:00
|
|
|
Value(Value&& val) { memcpy(buf, val.buf, 24); }
|
|
|
|
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
|
|
|
}
|
|
|
|
|
|
|
|
template <class T>
|
|
|
|
bool is() {
|
|
|
|
return dynamic_cast<T*>((Object*)buf) != nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class T>
|
|
|
|
T* to() {
|
|
|
|
return dynamic_cast<T*>((Object*)buf);
|
|
|
|
}
|
|
|
|
|
|
|
|
Object& operator*() { return *(Object*)(buf); }
|
|
|
|
Object* operator->() { return (Object*)(buf); }
|
|
|
|
|
2024-07-26 18:32:27 +00:00
|
|
|
Result<Value> copy(Arena& arena) { return ((Object*)buf)->copy(arena); }
|
|
|
|
|
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
|
|
|
};
|
|
|
|
|
|
|
|
Value pod_to_value(PodObject* obj);
|
|
|
|
|
2024-07-26 18:32:27 +00:00
|
|
|
Result<Value> syntax_unwrap(Value& val);
|