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 {
|
||||
|
||||
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;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue