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:
parent
56f15d749e
commit
359a707663
1 changed files with 89 additions and 6 deletions
|
|
@ -13,7 +13,7 @@
|
||||||
namespace nix_irc {
|
namespace nix_irc {
|
||||||
|
|
||||||
constexpr uint32_t IR_MAGIC = 0x4E495258;
|
constexpr uint32_t IR_MAGIC = 0x4E495258;
|
||||||
constexpr uint32_t IR_VERSION = 2;
|
constexpr uint32_t IR_VERSION = 3;
|
||||||
|
|
||||||
enum class NodeType : uint8_t {
|
enum class NodeType : uint8_t {
|
||||||
CONST_INT = 0x01,
|
CONST_INT = 0x01,
|
||||||
|
|
@ -41,6 +41,11 @@ enum class NodeType : uint8_t {
|
||||||
ASSERT = 0x52,
|
ASSERT = 0x52,
|
||||||
THUNK = 0x60,
|
THUNK = 0x60,
|
||||||
FORCE = 0x61,
|
FORCE = 0x61,
|
||||||
|
LAMBDA_PATTERN = 0x70,
|
||||||
|
INHERIT = 0x71,
|
||||||
|
INHERIT_FROM = 0x72,
|
||||||
|
STRING_INTERPOLATION = 0x73,
|
||||||
|
BUILTIN_CALL = 0x74,
|
||||||
ERROR = 0xFF
|
ERROR = 0xFF
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -131,6 +136,25 @@ struct LambdaNode {
|
||||||
LambdaNode(uint32_t a, std::shared_ptr<Node> b, uint32_t l = 0);
|
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 {
|
struct AppNode {
|
||||||
std::shared_ptr<Node> func;
|
std::shared_ptr<Node> func;
|
||||||
std::shared_ptr<Node> arg;
|
std::shared_ptr<Node> arg;
|
||||||
|
|
@ -252,14 +276,70 @@ struct ListNode {
|
||||||
: elements(std::move(elems)), line(l) {}
|
: 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
|
// Node wraps a variant for type-safe AST
|
||||||
class Node {
|
class Node {
|
||||||
public:
|
public:
|
||||||
using Variant = std::variant<ConstIntNode, ConstFloatNode, ConstStringNode, ConstPathNode,
|
using Variant =
|
||||||
ConstBoolNode, ConstNullNode, ConstURINode, ConstLookupPathNode,
|
std::variant<ConstIntNode, ConstFloatNode, ConstStringNode, ConstPathNode, ConstBoolNode,
|
||||||
VarNode, LambdaNode, AppNode, BinaryOpNode, UnaryOpNode, ImportNode,
|
ConstNullNode, ConstURINode, ConstLookupPathNode, VarNode, LambdaNode, AppNode,
|
||||||
AttrsetNode, SelectNode, HasAttrNode, WithNode, IfNode, LetNode,
|
BinaryOpNode, UnaryOpNode, ImportNode, AttrsetNode, SelectNode, HasAttrNode,
|
||||||
LetRecNode, AssertNode, ThunkNode, ForceNode, ListNode>;
|
WithNode, IfNode, LetNode, LetRecNode, AssertNode, ThunkNode, ForceNode,
|
||||||
|
ListNode, LambdaPatternNode, InheritNode, InheritFromNode,
|
||||||
|
StringInterpolationNode, BuiltinCallNode>;
|
||||||
|
|
||||||
Variant data;
|
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 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 {
|
struct SourceFile {
|
||||||
std::string path;
|
std::string path;
|
||||||
std::string content;
|
std::string content;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue