valeri/src/common.hpp

239 lines
5 KiB
C++
Raw Normal View History

#pragma once
#include <concepts>
#include <cstdint>
#include <cstring>
#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;
};
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;
};
class String : public Object {
public:
2024-07-26 18:32:27 +00:00
String() {}
String(GcRoot<PodString>&& val) : _value(std::move(val)) {}
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)));
}
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-26 18:32:27 +00:00
virtual Result<Value> copy(Arena& arena) final;
private:
2024-07-26 18:32:27 +00:00
GcRoot<PodString> _value;
};
class Symbol : public Object {
public:
2024-07-26 18:32:27 +00:00
Symbol() {}
Symbol(GcRoot<PodSymbol>&& val) : _value(std::move(val)) {}
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)));
}
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-26 18:32:27 +00:00
virtual Result<Value> copy(Arena& arena) final;
private:
2024-07-26 18:32:27 +00:00
GcRoot<PodSymbol> _value;
};
class Syntax : public Object {
public:
2024-07-26 18:32:27 +00:00
Syntax() {}
Syntax(GcRoot<PodSyntax>&& val) : _value(std::move(val)) {}
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-26 19:20:13 +00:00
Result<Value> get_value(Arena& arena);
2024-07-26 18:32:27 +00:00
virtual Result<Value> copy(Arena& arena) final;
private:
2024-07-26 18:32:27 +00:00
GcRoot<PodSyntax> _value;
};
class Pair : public Object {
public:
2024-07-26 18:32:27 +00:00
Pair() {}
Pair(GcRoot<PodPair>&& val) : _value(std::move(val)) {}
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;
private:
2024-07-26 18:32:27 +00:00
GcRoot<PodPair> _value;
};
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;
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) {}
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;
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;
template <class T>
2024-07-26 18:32:27 +00:00
Value(T&& obj)
requires std::derived_from<T, Object>
{
2024-07-26 18:32:27 +00:00
new (buf) T(std::move(obj));
}
2024-07-26 19:20:13 +00:00
static Result<Value> create(Arena& arena, PodObject* obj);
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); }
private:
2024-07-26 18:32:27 +00:00
uint8_t buf[24];
};
2024-07-26 18:32:27 +00:00
Result<Value> syntax_unwrap(Value& val);