brewery
notashelf /
4aa514d83d1d0de7cc81f64a4a90e77c2339f501

nixir

public

Import-resolving Nix IR plugin

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