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 <raf@notashelf.dev>
Change-Id: I1f0e81a120a0c956b8068d81c42796616a6a6964
This commit is contained in:
raf 2026-02-23 20:42:56 +03:00
commit 359a707663
Signed by: NotAShelf
GPG key ID: 29D95B64378DB4BF

View file

@ -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<Node> b, uint32_t l = 0);
};
struct PatternField {
std::string name;
std::optional<std::shared_ptr<Node>> default_value;
PatternField(std::string n, std::optional<std::shared_ptr<Node>> def = std::nullopt)
: name(std::move(n)), default_value(std::move(def)) {}
};
struct LambdaPatternNode {
std::vector<PatternField> required_fields;
std::vector<PatternField> optional_fields;
std::optional<std::string> at_binding;
bool allow_extra;
std::shared_ptr<Node> body;
uint32_t line = 0;
LambdaPatternNode(std::shared_ptr<Node> b, uint32_t l = 0);
};
struct AppNode {
std::shared_ptr<Node> func;
std::shared_ptr<Node> arg;
@ -252,14 +276,70 @@ struct ListNode {
: elements(std::move(elems)), line(l) {}
};
struct InheritNode {
std::vector<std::string> names;
uint32_t line = 0;
InheritNode(std::vector<std::string> n = {}, uint32_t l = 0) : names(std::move(n)), line(l) {}
};
struct InheritFromNode {
std::shared_ptr<Node> source;
std::vector<std::string> names;
uint32_t line = 0;
InheritFromNode(std::shared_ptr<Node> src, std::vector<std::string> 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<Node> 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<Node> e) {
StringPart part;
part.type = Type::EXPR;
part.expr = std::move(e);
return part;
}
};
struct StringInterpolationNode {
std::vector<StringPart> parts;
uint32_t line = 0;
StringInterpolationNode(std::vector<StringPart> p = {}, uint32_t l = 0)
: parts(std::move(p)), line(l) {}
};
struct BuiltinCallNode {
std::string builtin_name;
std::vector<std::shared_ptr<Node>> args;
uint32_t line = 0;
BuiltinCallNode(std::string name, std::vector<std::shared_ptr<Node>> 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<ConstIntNode, ConstFloatNode, ConstStringNode, ConstPathNode,
ConstBoolNode, ConstNullNode, ConstURINode, ConstLookupPathNode,
VarNode, LambdaNode, AppNode, BinaryOpNode, UnaryOpNode, ImportNode,
AttrsetNode, SelectNode, HasAttrNode, WithNode, IfNode, LetNode,
LetRecNode, AssertNode, ThunkNode, ForceNode, ListNode>;
using Variant =
std::variant<ConstIntNode, ConstFloatNode, ConstStringNode, ConstPathNode, ConstBoolNode,
ConstNullNode, ConstURINode, ConstLookupPathNode, VarNode, LambdaNode, AppNode,
BinaryOpNode, UnaryOpNode, ImportNode, AttrsetNode, SelectNode, HasAttrNode,
WithNode, IfNode, LetNode, LetRecNode, AssertNode, ThunkNode, ForceNode,
ListNode, LambdaPatternNode, InheritNode, InheritFromNode,
StringInterpolationNode, BuiltinCallNode>;
Variant data;
@ -312,6 +392,9 @@ inline ThunkNode::ThunkNode(std::shared_ptr<Node> e, uint32_t l) : expr(std::mov
inline ForceNode::ForceNode(std::shared_ptr<Node> e, uint32_t l) : expr(std::move(e)), line(l) {}
inline LambdaPatternNode::LambdaPatternNode(std::shared_ptr<Node> b, uint32_t l)
: allow_extra(false), body(std::move(b)), line(l) {}
struct SourceFile {
std::string path;
std::string content;