diff --git a/src/irc/serializer.cpp b/src/irc/serializer.cpp index cc6cdc8..7a83e55 100644 --- a/src/irc/serializer.cpp +++ b/src/irc/serializer.cpp @@ -43,6 +43,7 @@ struct Serializer::Impl { if (node.holds()) return NodeType::UNARY_OP; if (node.holds()) return NodeType::ATTRSET; if (node.holds()) return NodeType::SELECT; + if (node.holds()) return NodeType::HAS_ATTR; if (node.holds()) return NodeType::WITH; if (node.holds()) return NodeType::IF; if (node.holds()) return NodeType::LET; @@ -100,6 +101,9 @@ struct Serializer::Impl { } else { write_u8(0); } + } else if (auto* n = node.get_if()) { + if (n->expr) write_node(*n->expr); + if (n->attr) write_node(*n->attr); } else if (auto* n = node.get_if()) { 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 read_node() { + NodeType type = static_cast(read_u8()); + uint32_t line = read_u32(); + + switch (type) { + case NodeType::CONST_INT: { + int64_t val = static_cast(read_u64()); + return std::make_shared(ConstIntNode(val, line)); + } + case NodeType::CONST_STRING: { + std::string val = read_string(); + return std::make_shared(ConstStringNode(val, line)); + } + case NodeType::CONST_PATH: { + std::string val = read_string(); + return std::make_shared(ConstPathNode(val, line)); + } + case NodeType::CONST_BOOL: { + bool val = read_u8() != 0; + return std::make_shared(ConstBoolNode(val, line)); + } + case NodeType::CONST_NULL: + return std::make_shared(ConstNullNode(line)); + case NodeType::VAR: { + uint32_t index = read_u32(); + return std::make_shared(VarNode(index, "", line)); + } + case NodeType::LAMBDA: { + uint32_t arity = read_u32(); + auto body = read_node(); + return std::make_shared(LambdaNode(arity, body, line)); + } + case NodeType::APP: { + auto func = read_node(); + auto arg = read_node(); + return std::make_shared(AppNode(func, arg, line)); + } + case NodeType::BINARY_OP: { + BinaryOp op = static_cast(read_u8()); + auto left = read_node(); + auto right = read_node(); + return std::make_shared(BinaryOpNode(op, left, right, line)); + } + case NodeType::UNARY_OP: { + UnaryOp op = static_cast(read_u8()); + auto operand = read_node(); + return std::make_shared(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(std::move(attrs)); + } + case NodeType::SELECT: { + auto expr = read_node(); + auto attr = read_node(); + return std::make_shared(SelectNode(expr, attr, line)); + } + case NodeType::HAS_ATTR: { + auto expr = read_node(); + auto attr = read_node(); + return std::make_shared(HasAttrNode(expr, attr, line)); + } + case NodeType::WITH: { + auto attrs = read_node(); + auto body = read_node(); + return std::make_shared(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(IfNode(cond, then_branch, else_branch, line)); + } + case NodeType::LET: { + uint32_t num_bindings = read_u32(); + std::vector>> 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(std::move(let)); + } + case NodeType::LETREC: { + uint32_t num_bindings = read_u32(); + std::vector>> 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(std::move(letrec)); + } + case NodeType::ASSERT: { + auto cond = read_node(); + auto body = read_node(); + return std::make_shared(AssertNode(cond, body, line)); + } + default: + throw std::runtime_error("Unknown node type in IR"); + } + } }; Deserializer::Deserializer() : pImpl(std::make_unique()) {} @@ -256,7 +376,7 @@ IRModule Deserializer::deserialize(const std::vector& data) { } if (pImpl->read_u8()) { - // TODO: deserialize AST + module.entry = pImpl->read_node(); } return module;