brewery
notashelf /
303b211d74d5f3432d10b21c7c19681cc29c5a0e

nixir

public

Import-resolving Nix IR plugin

Star0tarball
clone
ssh://git@git.notashelf.dev:33/notashelf/nixir.git
src/irc/types.hC277 lines7.0 KB
1
#ifndef NIX_IRC_TYPES_H
2
#define NIX_IRC_TYPES_H
3
4
#include <cstdint>
5
#include <string>
6
#include <vector>
7
#include <unordered_map>
8
#include <optional>
9
#include <memory>
10
#include <variant>
11
#include <fstream>
12
#include <sstream>
13
14
namespace nix_irc {
15
16
constexpr uint32_t IR_MAGIC = 0x4E495258;
17
constexpr uint32_t IR_VERSION = 1;
18
19
enum class NodeType : uint8_t {
20
    CONST_INT = 0x01,
21
    CONST_STRING = 0x02,
22
    CONST_PATH = 0x03,
23
    CONST_BOOL = 0x04,
24
    CONST_NULL = 0x05,
25
    VAR = 0x10,
26
    LAMBDA = 0x20,
27
    APP = 0x21,
28
    BINARY_OP = 0x22,
29
    UNARY_OP = 0x23,
30
    ATTRSET = 0x30,
31
    SELECT = 0x31,
32
    WITH = 0x32,
33
    IF = 0x40,
34
    LET = 0x50,
35
    LETREC = 0x51,
36
    ASSERT = 0x52,
37
    THUNK = 0x60,
38
    FORCE = 0x61,
39
    ERROR = 0xFF
40
};
41
42
enum class BinaryOp : uint8_t {
43
    ADD, SUB, MUL, DIV, CONCAT,
44
    EQ, NE, LT, GT, LE, GE,
45
    AND, OR, IMPL
46
};
47
48
enum class UnaryOp : uint8_t {
49
    NEG, NOT
50
};
51
52
// Forward declare Node for use in shared_ptr
53
class Node;
54
55
struct ConstIntNode {
56
    int64_t value;
57
    uint32_t line = 0;
58
    ConstIntNode(int64_t v = 0, uint32_t l = 0) : value(v), line(l) {}
59
};
60
61
struct ConstStringNode {
62
    std::string value;
63
    uint32_t line = 0;
64
    ConstStringNode(std::string v = "", uint32_t l = 0) : value(std::move(v)), line(l) {}
65
};
66
67
struct ConstPathNode {
68
    std::string value;
69
    uint32_t line = 0;
70
    ConstPathNode(std::string v = "", uint32_t l = 0) : value(std::move(v)), line(l) {}
71
};
72
73
struct ConstBoolNode {
74
    bool value;
75
    uint32_t line = 0;
76
    ConstBoolNode(bool v = false, uint32_t l = 0) : value(v), line(l) {}
77
};
78
79
struct ConstNullNode {
80
    uint32_t line = 0;
81
    ConstNullNode(uint32_t l = 0) : line(l) {}
82
};
83
84
struct VarNode {
85
    uint32_t index = 0;
86
    std::optional<std::string> name;
87
    uint32_t line = 0;
88
    VarNode(uint32_t idx = 0, std::string n = "", uint32_t l = 0)
89
        : index(idx), name(n.empty() ? std::nullopt : std::optional<std::string>(n)), line(l) {}
90
};
91
92
struct LambdaNode {
93
    uint32_t arity = 1;
94
    std::shared_ptr<Node> body;
95
    std::optional<std::string> param_name;
96
    uint32_t line = 0;
97
    LambdaNode(uint32_t a, std::shared_ptr<Node> b, uint32_t l = 0);
98
};
99
100
struct AppNode {
101
    std::shared_ptr<Node> func;
102
    std::shared_ptr<Node> arg;
103
    uint32_t line = 0;
104
    AppNode(std::shared_ptr<Node> f, std::shared_ptr<Node> a, uint32_t l = 0);
105
};
106
107
struct BinaryOpNode {
108
    BinaryOp op;
109
    std::shared_ptr<Node> left;
110
    std::shared_ptr<Node> right;
111
    uint32_t line = 0;
112
    BinaryOpNode(BinaryOp o, std::shared_ptr<Node> l, std::shared_ptr<Node> r, uint32_t ln = 0);
113
};
114
115
struct UnaryOpNode {
116
    UnaryOp op;
117
    std::shared_ptr<Node> operand;
118
    uint32_t line = 0;
119
    UnaryOpNode(UnaryOp o, std::shared_ptr<Node> operand, uint32_t l = 0);
120
};
121
122
struct AttrsetNode {
123
    std::vector<std::pair<std::string, std::shared_ptr<Node>>> attrs;
124
    bool recursive = false;
125
    uint32_t line = 0;
126
    AttrsetNode(bool rec = false, uint32_t l = 0) : recursive(rec), line(l) {}
127
};
128
129
struct SelectNode {
130
    std::shared_ptr<Node> expr;
131
    std::shared_ptr<Node> attr;
132
    std::optional<std::shared_ptr<Node>> default_expr;
133
    uint32_t line = 0;
134
    SelectNode(std::shared_ptr<Node> e, std::shared_ptr<Node> a, uint32_t l = 0);
135
};
136
137
struct WithNode {
138
    std::shared_ptr<Node> attrs;
139
    std::shared_ptr<Node> body;
140
    uint32_t line = 0;
141
    WithNode(std::shared_ptr<Node> a, std::shared_ptr<Node> b, uint32_t l = 0);
142
};
143
144
struct IfNode {
145
    std::shared_ptr<Node> cond;
146
    std::shared_ptr<Node> then_branch;
147
    std::shared_ptr<Node> else_branch;
148
    uint32_t line = 0;
149
    IfNode(std::shared_ptr<Node> c, std::shared_ptr<Node> t, std::shared_ptr<Node> e, uint32_t l = 0);
150
};
151
152
struct LetNode {
153
    std::vector<std::pair<std::string, std::shared_ptr<Node>>> bindings;
154
    std::shared_ptr<Node> body;
155
    uint32_t line = 0;
156
    LetNode(std::shared_ptr<Node> b, uint32_t l = 0);
157
};
158
159
struct LetRecNode {
160
    std::vector<std::pair<std::string, std::shared_ptr<Node>>> bindings;
161
    std::shared_ptr<Node> body;
162
    uint32_t line = 0;
163
    LetRecNode(std::shared_ptr<Node> b, uint32_t l = 0);
164
};
165
166
struct AssertNode {
167
    std::shared_ptr<Node> cond;
168
    std::shared_ptr<Node> body;
169
    uint32_t line = 0;
170
    AssertNode(std::shared_ptr<Node> c, std::shared_ptr<Node> b, uint32_t l = 0);
171
};
172
173
struct ThunkNode {
174
    std::shared_ptr<Node> expr;
175
    uint32_t line = 0;
176
    ThunkNode(std::shared_ptr<Node> e, uint32_t l = 0);
177
};
178
179
struct ForceNode {
180
    std::shared_ptr<Node> expr;
181
    uint32_t line = 0;
182
    ForceNode(std::shared_ptr<Node> e, uint32_t l = 0);
183
};
184
185
// Node wraps a variant for type-safe AST
186
class Node {
187
public:
188
    using Variant = std::variant<
189
        ConstIntNode,
190
        ConstStringNode,
191
        ConstPathNode,
192
        ConstBoolNode,
193
        ConstNullNode,
194
        VarNode,
195
        LambdaNode,
196
        AppNode,
197
        BinaryOpNode,
198
        UnaryOpNode,
199
        AttrsetNode,
200
        SelectNode,
201
        WithNode,
202
        IfNode,
203
        LetNode,
204
        LetRecNode,
205
        AssertNode,
206
        ThunkNode,
207
        ForceNode
208
    >;
209
210
    Variant data;
211
212
    template<typename T>
213
    Node(T&& value) : data(std::forward<T>(value)) {}
214
215
    template<typename T>
216
    T* get_if() { return std::get_if<T>(&data); }
217
218
    template<typename T>
219
    const T* get_if() const { return std::get_if<T>(&data); }
220
221
    template<typename T>
222
    bool holds() const { return std::holds_alternative<T>(data); }
223
};
224
225
// Constructor implementations
226
inline LambdaNode::LambdaNode(uint32_t a, std::shared_ptr<Node> b, uint32_t l)
227
    : arity(a), body(b), line(l) {}
228
229
inline AppNode::AppNode(std::shared_ptr<Node> f, std::shared_ptr<Node> a, uint32_t l)
230
    : func(f), arg(a), line(l) {}
231
232
inline BinaryOpNode::BinaryOpNode(BinaryOp o, std::shared_ptr<Node> l, std::shared_ptr<Node> r, uint32_t ln)
233
    : op(o), left(l), right(r), line(ln) {}
234
235
inline UnaryOpNode::UnaryOpNode(UnaryOp o, std::shared_ptr<Node> operand, uint32_t l)
236
    : op(o), operand(operand), line(l) {}
237
238
inline SelectNode::SelectNode(std::shared_ptr<Node> e, std::shared_ptr<Node> a, uint32_t l)
239
    : expr(e), attr(a), line(l) {}
240
241
inline WithNode::WithNode(std::shared_ptr<Node> a, std::shared_ptr<Node> b, uint32_t l)
242
    : attrs(a), body(b), line(l) {}
243
244
inline IfNode::IfNode(std::shared_ptr<Node> c, std::shared_ptr<Node> t, std::shared_ptr<Node> e, uint32_t l)
245
    : cond(c), then_branch(t), else_branch(e), line(l) {}
246
247
inline LetNode::LetNode(std::shared_ptr<Node> b, uint32_t l)
248
    : body(b), line(l) {}
249
250
inline LetRecNode::LetRecNode(std::shared_ptr<Node> b, uint32_t l)
251
    : body(b), line(l) {}
252
253
inline AssertNode::AssertNode(std::shared_ptr<Node> c, std::shared_ptr<Node> b, uint32_t l)
254
    : cond(c), body(b), line(l) {}
255
256
inline ThunkNode::ThunkNode(std::shared_ptr<Node> e, uint32_t l)
257
    : expr(e), line(l) {}
258
259
inline ForceNode::ForceNode(std::shared_ptr<Node> e, uint32_t l)
260
    : expr(e), line(l) {}
261
262
struct SourceFile {
263
    std::string path;
264
    std::string content;
265
    std::shared_ptr<Node> ast;
266
};
267
268
struct IRModule {
269
    uint32_t version = IR_VERSION;
270
    std::vector<SourceFile> sources;
271
    std::vector<std::pair<std::string, std::string>> imports;
272
    std::shared_ptr<Node> entry;
273
    std::unordered_map<std::string, uint32_t> string_table;
274
};
275
276
}
277
#endif