From 359a7076636a1eac904f37f418d71ddc5f89c023 Mon Sep 17 00:00:00 2001 From: NotAShelf Date: Mon, 23 Feb 2026 20:42:56 +0300 Subject: [PATCH] irc/types: IR type extensions Updates IR_VERSION to 3. In an effort to support more features of the Nix language, implements 5 new node type constants: - `LAMBDA_PATTERN` = `0x70` - Lambda with pattern matching - `INHERIT` = `0x71` - Simple inherit expressions - `INHERIT_FROM` = `0x72` - Inherit from source expression - `STRING_INTERPOLATION` = `0x73` - String with interpolated parts - `BUILTIN_CALL` = `0x74` - Builtin function call and some struct definitions before the Node class, such as `PatternField`. Those will come in handy for suppporting the entire Nixpkgs library. Signed-off-by: NotAShelf Change-Id: I1f0e81a120a0c956b8068d81c42796616a6a6964 --- src/irc/types.h | 95 +++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 89 insertions(+), 6 deletions(-) diff --git a/src/irc/types.h b/src/irc/types.h index 7b0765d..7a4c754 100644 --- a/src/irc/types.h +++ b/src/irc/types.h @@ -13,7 +13,7 @@ namespace nix_irc { constexpr uint32_t IR_MAGIC = 0x4E495258; -constexpr uint32_t IR_VERSION = 2; +constexpr uint32_t IR_VERSION = 3; enum class NodeType : uint8_t { CONST_INT = 0x01, @@ -41,6 +41,11 @@ enum class NodeType : uint8_t { ASSERT = 0x52, THUNK = 0x60, FORCE = 0x61, + LAMBDA_PATTERN = 0x70, + INHERIT = 0x71, + INHERIT_FROM = 0x72, + STRING_INTERPOLATION = 0x73, + BUILTIN_CALL = 0x74, ERROR = 0xFF }; @@ -131,6 +136,25 @@ struct LambdaNode { LambdaNode(uint32_t a, std::shared_ptr b, uint32_t l = 0); }; +struct PatternField { + std::string name; + std::optional> default_value; + + PatternField(std::string n, std::optional> def = std::nullopt) + : name(std::move(n)), default_value(std::move(def)) {} +}; + +struct LambdaPatternNode { + std::vector required_fields; + std::vector optional_fields; + std::optional at_binding; + bool allow_extra; + std::shared_ptr body; + uint32_t line = 0; + + LambdaPatternNode(std::shared_ptr b, uint32_t l = 0); +}; + struct AppNode { std::shared_ptr func; std::shared_ptr arg; @@ -252,14 +276,70 @@ struct ListNode { : elements(std::move(elems)), line(l) {} }; +struct InheritNode { + std::vector names; + uint32_t line = 0; + + InheritNode(std::vector n = {}, uint32_t l = 0) : names(std::move(n)), line(l) {} +}; + +struct InheritFromNode { + std::shared_ptr source; + std::vector names; + uint32_t line = 0; + + InheritFromNode(std::shared_ptr src, std::vector n, uint32_t l = 0) + : source(std::move(src)), names(std::move(n)), line(l) {} +}; + +struct StringPart { + enum class Type { LITERAL, EXPR }; + Type type; + std::string literal; + std::shared_ptr expr; + + static StringPart make_literal(std::string lit) { + StringPart part; + part.type = Type::LITERAL; + part.literal = std::move(lit); + return part; + } + + static StringPart make_expr(std::shared_ptr e) { + StringPart part; + part.type = Type::EXPR; + part.expr = std::move(e); + return part; + } +}; + +struct StringInterpolationNode { + std::vector parts; + uint32_t line = 0; + + StringInterpolationNode(std::vector p = {}, uint32_t l = 0) + : parts(std::move(p)), line(l) {} +}; + +struct BuiltinCallNode { + std::string builtin_name; + std::vector> args; + uint32_t line = 0; + + BuiltinCallNode(std::string name, std::vector> a = {}, uint32_t l = 0) + : builtin_name(std::move(name)), args(std::move(a)), line(l) {} +}; + // Node wraps a variant for type-safe AST class Node { public: - using Variant = std::variant; + using Variant = + std::variant; Variant data; @@ -312,6 +392,9 @@ inline ThunkNode::ThunkNode(std::shared_ptr e, uint32_t l) : expr(std::mov inline ForceNode::ForceNode(std::shared_ptr e, uint32_t l) : expr(std::move(e)), line(l) {} +inline LambdaPatternNode::LambdaPatternNode(std::shared_ptr b, uint32_t l) + : allow_extra(false), body(std::move(b)), line(l) {} + struct SourceFile { std::string path; std::string content;