serializer: add HasAttrNode binary encoding
Signed-off-by: NotAShelf <raf@notashelf.dev> Change-Id: Ifdbd53aafc8291c78c273e2c9092fdf26a6a6964
This commit is contained in:
parent
a69385c5ca
commit
4b97433642
1 changed files with 121 additions and 1 deletions
|
|
@ -43,6 +43,7 @@ struct Serializer::Impl {
|
|||
if (node.holds<UnaryOpNode>()) return NodeType::UNARY_OP;
|
||||
if (node.holds<AttrsetNode>()) return NodeType::ATTRSET;
|
||||
if (node.holds<SelectNode>()) return NodeType::SELECT;
|
||||
if (node.holds<HasAttrNode>()) return NodeType::HAS_ATTR;
|
||||
if (node.holds<WithNode>()) return NodeType::WITH;
|
||||
if (node.holds<IfNode>()) return NodeType::IF;
|
||||
if (node.holds<LetNode>()) return NodeType::LET;
|
||||
|
|
@ -100,6 +101,9 @@ struct Serializer::Impl {
|
|||
} else {
|
||||
write_u8(0);
|
||||
}
|
||||
} else if (auto* n = node.get_if<HasAttrNode>()) {
|
||||
if (n->expr) write_node(*n->expr);
|
||||
if (n->attr) write_node(*n->attr);
|
||||
} else if (auto* n = node.get_if<WithNode>()) {
|
||||
if (n->attrs) write_node(*n->attrs);
|
||||
if (n->body) write_node(*n->body);
|
||||
|
|
@ -204,6 +208,122 @@ struct Deserializer::Impl {
|
|||
pos += len;
|
||||
return str;
|
||||
}
|
||||
|
||||
std::shared_ptr<Node> read_node() {
|
||||
NodeType type = static_cast<NodeType>(read_u8());
|
||||
uint32_t line = read_u32();
|
||||
|
||||
switch (type) {
|
||||
case NodeType::CONST_INT: {
|
||||
int64_t val = static_cast<int64_t>(read_u64());
|
||||
return std::make_shared<Node>(ConstIntNode(val, line));
|
||||
}
|
||||
case NodeType::CONST_STRING: {
|
||||
std::string val = read_string();
|
||||
return std::make_shared<Node>(ConstStringNode(val, line));
|
||||
}
|
||||
case NodeType::CONST_PATH: {
|
||||
std::string val = read_string();
|
||||
return std::make_shared<Node>(ConstPathNode(val, line));
|
||||
}
|
||||
case NodeType::CONST_BOOL: {
|
||||
bool val = read_u8() != 0;
|
||||
return std::make_shared<Node>(ConstBoolNode(val, line));
|
||||
}
|
||||
case NodeType::CONST_NULL:
|
||||
return std::make_shared<Node>(ConstNullNode(line));
|
||||
case NodeType::VAR: {
|
||||
uint32_t index = read_u32();
|
||||
return std::make_shared<Node>(VarNode(index, "", line));
|
||||
}
|
||||
case NodeType::LAMBDA: {
|
||||
uint32_t arity = read_u32();
|
||||
auto body = read_node();
|
||||
return std::make_shared<Node>(LambdaNode(arity, body, line));
|
||||
}
|
||||
case NodeType::APP: {
|
||||
auto func = read_node();
|
||||
auto arg = read_node();
|
||||
return std::make_shared<Node>(AppNode(func, arg, line));
|
||||
}
|
||||
case NodeType::BINARY_OP: {
|
||||
BinaryOp op = static_cast<BinaryOp>(read_u8());
|
||||
auto left = read_node();
|
||||
auto right = read_node();
|
||||
return std::make_shared<Node>(BinaryOpNode(op, left, right, line));
|
||||
}
|
||||
case NodeType::UNARY_OP: {
|
||||
UnaryOp op = static_cast<UnaryOp>(read_u8());
|
||||
auto operand = read_node();
|
||||
return std::make_shared<Node>(UnaryOpNode(op, operand, line));
|
||||
}
|
||||
case NodeType::ATTRSET: {
|
||||
bool recursive = read_u8() != 0;
|
||||
uint32_t num_attrs = read_u32();
|
||||
AttrsetNode attrs(recursive, line);
|
||||
for (uint32_t i = 0; i < num_attrs; i++) {
|
||||
std::string key = read_string();
|
||||
auto val = read_node();
|
||||
attrs.attrs.push_back({key, val});
|
||||
}
|
||||
return std::make_shared<Node>(std::move(attrs));
|
||||
}
|
||||
case NodeType::SELECT: {
|
||||
auto expr = read_node();
|
||||
auto attr = read_node();
|
||||
return std::make_shared<Node>(SelectNode(expr, attr, line));
|
||||
}
|
||||
case NodeType::HAS_ATTR: {
|
||||
auto expr = read_node();
|
||||
auto attr = read_node();
|
||||
return std::make_shared<Node>(HasAttrNode(expr, attr, line));
|
||||
}
|
||||
case NodeType::WITH: {
|
||||
auto attrs = read_node();
|
||||
auto body = read_node();
|
||||
return std::make_shared<Node>(WithNode(attrs, body, line));
|
||||
}
|
||||
case NodeType::IF: {
|
||||
auto cond = read_node();
|
||||
auto then_branch = read_node();
|
||||
auto else_branch = read_node();
|
||||
return std::make_shared<Node>(IfNode(cond, then_branch, else_branch, line));
|
||||
}
|
||||
case NodeType::LET: {
|
||||
uint32_t num_bindings = read_u32();
|
||||
std::vector<std::pair<std::string, std::shared_ptr<Node>>> bindings;
|
||||
for (uint32_t i = 0; i < num_bindings; i++) {
|
||||
std::string key = read_string();
|
||||
auto val = read_node();
|
||||
bindings.push_back({key, val});
|
||||
}
|
||||
auto body = read_node();
|
||||
LetNode let(body, line);
|
||||
let.bindings = std::move(bindings);
|
||||
return std::make_shared<Node>(std::move(let));
|
||||
}
|
||||
case NodeType::LETREC: {
|
||||
uint32_t num_bindings = read_u32();
|
||||
std::vector<std::pair<std::string, std::shared_ptr<Node>>> bindings;
|
||||
for (uint32_t i = 0; i < num_bindings; i++) {
|
||||
std::string key = read_string();
|
||||
auto val = read_node();
|
||||
bindings.push_back({key, val});
|
||||
}
|
||||
auto body = read_node();
|
||||
LetRecNode letrec(body, line);
|
||||
letrec.bindings = std::move(bindings);
|
||||
return std::make_shared<Node>(std::move(letrec));
|
||||
}
|
||||
case NodeType::ASSERT: {
|
||||
auto cond = read_node();
|
||||
auto body = read_node();
|
||||
return std::make_shared<Node>(AssertNode(cond, body, line));
|
||||
}
|
||||
default:
|
||||
throw std::runtime_error("Unknown node type in IR");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Deserializer::Deserializer() : pImpl(std::make_unique<Impl>()) {}
|
||||
|
|
@ -256,7 +376,7 @@ IRModule Deserializer::deserialize(const std::vector<uint8_t>& data) {
|
|||
}
|
||||
|
||||
if (pImpl->read_u8()) {
|
||||
// TODO: deserialize AST
|
||||
module.entry = pImpl->read_node();
|
||||
}
|
||||
|
||||
return module;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue