brewery
notashelf /
4b97433642cd8e430a2738700b7887e33a280e19

nixir

public

Import-resolving Nix IR plugin

Star0tarball
clone
ssh://git@git.notashelf.dev:33/notashelf/nixir.git

Commit 4b97433642cd

tarball

NotAShelf <raf@notashelf.dev> · 2026-02-21 21:07 UTC

unverified1 files changed+121-1
serializer: add `HasAttrNode` binary encoding

Signed-off-by: NotAShelf <raf@notashelf.dev>
Change-Id: Ifdbd53aafc8291c78c273e2c9092fdf26a6a6964
diff --git a/src/irc/serializer.cpp b/src/irc/serializer.cppindex cc6cdc8..7a83e55 100644--- a/src/irc/serializer.cpp+++ b/src/irc/serializer.cpp@@ -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;