2023-04-07 16:04:30 -04:00
|
|
|
#include "Compiler.h"
|
2023-04-07 23:21:15 -04:00
|
|
|
|
|
|
|
namespace {
|
|
|
|
template <typename T>
|
|
|
|
void SerializeDirect(std::ostringstream& s, const T& v) {
|
|
|
|
s.write(reinterpret_cast<const char*>(&v), sizeof v);
|
|
|
|
}
|
|
|
|
|
|
|
|
void SerializeString(std::ostringstream& s, const NVL::String& st) {
|
|
|
|
u16 v = st.size() * sizeof NVL::Char;
|
|
|
|
s.write(reinterpret_cast<const char*>(&v), sizeof v);
|
|
|
|
s.write(reinterpret_cast<const char*>(st.c_str()), v);
|
|
|
|
}
|
|
|
|
|
|
|
|
void SerializeVariable(std::ostringstream& s, const NVL::Environment::Variable& v) {
|
|
|
|
using NVL::Environment::Type;
|
|
|
|
SerializeDirect(s, v.type);
|
|
|
|
switch (v.type) {
|
|
|
|
case Type::Array:
|
|
|
|
{
|
|
|
|
const auto& e = std::get<NVL::Vector<NVL::Environment::Variable>>(v.value);
|
|
|
|
SerializeDirect(s, static_cast<u16>(e.size()));
|
|
|
|
for (const auto& x : e) {
|
|
|
|
SerializeVariable(s, x);
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
case Type::Nil:
|
|
|
|
return;
|
|
|
|
case Type::Number:
|
|
|
|
case Type::StaticReference:
|
|
|
|
SerializeDirect(s, std::get<NVL::Number>(v.value));
|
|
|
|
return;
|
|
|
|
case Type::String:
|
|
|
|
SerializeString(s, std::get<NVL::String>(v.value));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename T>
|
|
|
|
void DeserializeDirect(std::istringstream& s, T& v) {
|
|
|
|
s.read(reinterpret_cast<char*>(&v), sizeof v);
|
|
|
|
}
|
|
|
|
|
|
|
|
NVL::String DeserializeString(std::istringstream& s) {
|
|
|
|
u16 size{};
|
|
|
|
DeserializeDirect(s, size);
|
|
|
|
u8* str = new u8[size + sizeof NVL::Char];
|
|
|
|
s.read(reinterpret_cast<char*>(str), size);
|
|
|
|
reinterpret_cast<NVL::Char*>(str)[size / sizeof NVL::Char] = u'\0';
|
|
|
|
NVL::String st = NVL::String(reinterpret_cast<NVL::Char*>(str));
|
|
|
|
delete[] str;
|
|
|
|
return st;
|
|
|
|
}
|
|
|
|
|
|
|
|
NVL::Environment::Variable DeserializeVariable(std::istringstream& s) {
|
|
|
|
using NVL::Environment::Type;
|
|
|
|
NVL::Environment::Type t{};
|
|
|
|
DeserializeDirect(s, t);
|
|
|
|
switch (t) {
|
|
|
|
case Type::Array:
|
|
|
|
{
|
|
|
|
u16 size{};
|
|
|
|
NVL::Vector<NVL::Environment::Variable> vs{};
|
|
|
|
DeserializeDirect(s, size);
|
|
|
|
for (u16 i = 0; i < size; i++) {
|
|
|
|
vs.push_back(DeserializeVariable(s));
|
|
|
|
}
|
|
|
|
return vs;
|
|
|
|
}
|
|
|
|
case Type::Nil:
|
|
|
|
return {};
|
|
|
|
case Type::Number:
|
|
|
|
case Type::StaticReference:
|
|
|
|
{
|
|
|
|
NVL::Number n{};
|
|
|
|
DeserializeDirect(s, n);
|
|
|
|
return { n, t == Type::StaticReference };
|
|
|
|
}
|
|
|
|
case Type::String:
|
|
|
|
return DeserializeString(s);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2023-04-07 16:04:30 -04:00
|
|
|
|
|
|
|
namespace NVL::Compiler {
|
2023-04-07 23:21:15 -04:00
|
|
|
Environment::Variable StaticEval(Vector<String>& refs, const Parse::Object& obj) {
|
|
|
|
Environment::Variable actual = Environment::Eval(obj);
|
|
|
|
if (actual.type == Environment::Type::Procedure) {
|
|
|
|
u32 proc_index = -1; // lol
|
|
|
|
const String& proc = std::get<String>(obj.value);
|
|
|
|
for (u32 i = 0; i < refs.size(); i++) {
|
|
|
|
if (refs[i] == proc) {
|
|
|
|
proc_index = i;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (proc_index == -1) {
|
|
|
|
proc_index = refs.size();
|
|
|
|
refs.push_back(proc);
|
|
|
|
}
|
|
|
|
return Environment::Variable(proc_index, true);
|
|
|
|
}
|
|
|
|
return actual;
|
|
|
|
}
|
2023-04-07 16:04:30 -04:00
|
|
|
|
2023-04-07 23:21:15 -04:00
|
|
|
NVLGraph Compile(const Vector<Parse::Scene>& scenes, i32 entry_scene_index) {
|
|
|
|
std::vector<_DirectedGraphNode> nodes{};
|
|
|
|
Vector<String> procedure_names;
|
2023-04-07 16:04:30 -04:00
|
|
|
|
2023-04-07 23:21:15 -04:00
|
|
|
_DirectedGraphNode n{};
|
2023-04-07 16:04:30 -04:00
|
|
|
for (auto& c : scenes[entry_scene_index].get()) {
|
|
|
|
Vector<Environment::Variable> s{};
|
2023-04-07 23:21:15 -04:00
|
|
|
|
|
|
|
for (auto& v : c) {
|
|
|
|
s.push_back(StaticEval(procedure_names, v));
|
|
|
|
}
|
|
|
|
|
|
|
|
// TODO route nodes when JUMP
|
|
|
|
|
|
|
|
n.sequence.push_back(s);
|
|
|
|
}
|
|
|
|
nodes.push_back(n);
|
|
|
|
return NVLGraph{ nodes, procedure_names };
|
|
|
|
}
|
|
|
|
|
|
|
|
std::ostringstream Serialize(const NVLGraph& g) {
|
|
|
|
std::ostringstream s;
|
|
|
|
|
|
|
|
SerializeDirect(s, static_cast<u16>(g.static_refs.size()));
|
|
|
|
for (const String& r : g.static_refs) {
|
|
|
|
SerializeString(s, r);
|
|
|
|
}
|
|
|
|
SerializeDirect(s, static_cast<u16>(g.nodes.size()));
|
|
|
|
for (const _DirectedGraphNode& n : g.nodes) {
|
|
|
|
SerializeDirect(s, static_cast<u16>(n.sequence.size()));
|
|
|
|
for (const Vector<Environment::Variable>& c : n.sequence) {
|
|
|
|
SerializeDirect(s, static_cast<u16>(c.size()));
|
|
|
|
for (const Environment::Variable& v : c) {
|
|
|
|
SerializeVariable(s, v);
|
|
|
|
}
|
2023-04-07 16:04:30 -04:00
|
|
|
}
|
|
|
|
}
|
2023-04-07 23:21:15 -04:00
|
|
|
return s;
|
2023-04-07 16:04:30 -04:00
|
|
|
}
|
|
|
|
|
2023-04-07 23:21:15 -04:00
|
|
|
NVLGraph Deserialize(std::istringstream& buf) {
|
|
|
|
NVLGraph g{};
|
|
|
|
|
|
|
|
u16 size{};
|
|
|
|
DeserializeDirect(buf, size);
|
|
|
|
for (u16 i = 0; i < size; i++) {
|
|
|
|
g.static_refs.push_back(DeserializeString(buf));
|
|
|
|
}
|
|
|
|
|
|
|
|
DeserializeDirect(buf, size);
|
|
|
|
for (u16 i = 0; i < size; i++) {
|
|
|
|
_DirectedGraphNode n{};
|
|
|
|
u16 size2{};
|
|
|
|
DeserializeDirect(buf, size2);
|
|
|
|
for (u16 j = 0; j < size2; j++) {
|
|
|
|
Vector<Environment::Variable> cmd{};
|
|
|
|
u16 size3{};
|
|
|
|
DeserializeDirect(buf, size3);
|
|
|
|
for (u16 k = 0; k < size3; k++) {
|
|
|
|
cmd.push_back(DeserializeVariable(buf));
|
|
|
|
}
|
|
|
|
n.sequence.push_back(cmd);
|
|
|
|
}
|
|
|
|
g.nodes.push_back(n);
|
|
|
|
}
|
|
|
|
return g;
|
2023-04-07 16:04:30 -04:00
|
|
|
}
|
|
|
|
}
|