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;
|
|
|
|
};
|
|
|
|
|
|
|
|
class Nil : public Object {
|
|
|
|
public:
|
|
|
|
Nil() {}
|
|
|
|
|
|
|
|
virtual Tag tag() final { return Tag::Nil; }
|
|
|
|
};
|
|
|
|
|
|
|
|
class String : public Object {
|
|
|
|
public:
|
2024-07-20 21:42:49 +00:00
|
|
|
String() : _value(0) {}
|
2024-07-19 01:29:30 +00:00
|
|
|
String(PodString* val) : _value(val) {}
|
|
|
|
virtual Tag tag() final { return Tag::String; }
|
|
|
|
|
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));
|
|
|
|
|
|
|
|
return String(pod_string);
|
|
|
|
}
|
|
|
|
|
2024-07-19 01:29:30 +00:00
|
|
|
private:
|
|
|
|
PodString* _value;
|
|
|
|
};
|
|
|
|
|
|
|
|
class Symbol : public Object {
|
|
|
|
public:
|
2024-07-20 21:42:49 +00:00
|
|
|
Symbol() : _value(0) {}
|
2024-07-19 01:29:30 +00:00
|
|
|
Symbol(PodSymbol* val) : _value(val) {}
|
|
|
|
virtual Tag tag() final { return Tag::Symbol; }
|
|
|
|
|
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));
|
|
|
|
|
|
|
|
return Symbol(pod_symbol);
|
|
|
|
}
|
|
|
|
|
2024-07-19 01:29:30 +00:00
|
|
|
private:
|
|
|
|
PodSymbol* _value;
|
|
|
|
};
|
|
|
|
|
|
|
|
class Syntax : public Object {
|
|
|
|
public:
|
|
|
|
Syntax(PodSyntax* val) : _value(val) {}
|
|
|
|
Syntax(String filename, String modulename, Value expression);
|
|
|
|
virtual Tag tag() final { return Tag::Syntax; }
|
|
|
|
|
|
|
|
Value get_value();
|
|
|
|
|
|
|
|
private:
|
|
|
|
PodSyntax* _value;
|
|
|
|
};
|
|
|
|
|
|
|
|
class Pair : public Object {
|
|
|
|
public:
|
|
|
|
Pair(PodPair* value) : _value(value) {}
|
|
|
|
virtual Tag tag() final { return Tag::Pair; }
|
|
|
|
|
|
|
|
private:
|
|
|
|
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; }
|
|
|
|
|
|
|
|
private:
|
|
|
|
int64_t _value;
|
|
|
|
};
|
|
|
|
|
|
|
|
class Float : public Object {
|
|
|
|
public:
|
|
|
|
Float() : _value(0) {}
|
|
|
|
virtual ~Float() = default;
|
|
|
|
|
|
|
|
virtual Tag tag() final { return Tag::Float; }
|
|
|
|
|
|
|
|
double value() { return _value; }
|
|
|
|
|
|
|
|
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(); }
|
|
|
|
|
|
|
|
template <class T>
|
|
|
|
Value(const T& obj)
|
|
|
|
requires std::derived_from<T, Object> && (sizeof(T) <= 16)
|
|
|
|
{
|
|
|
|
new (buf) T(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); }
|
|
|
|
|
|
|
|
private:
|
|
|
|
uint8_t buf[16];
|
|
|
|
};
|
|
|
|
|
|
|
|
Value pod_to_value(PodObject* obj);
|
|
|
|
|
|
|
|
Value syntax_unwrap(Value);
|