brewery
notashelf /
3441853eefef2a3380fa4008e916bb70e83a4825

nixir

public

Import-resolving Nix IR plugin

Star0tarball
clone
ssh://git@git.notashelf.dev:33/notashelf/nixir.git
src/irc/types.hC289 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 = 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
    HAS_ATTR = 0x32,
33
    WITH = 0x33,
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
    uint32_t line = 0;
98
    LambdaNode(uint32_t a, std::shared_ptr<Node> b, uint32_t l = 0);
99
};
100
101
struct AppNode {
102
    std::shared_ptr<Node> func;
103
    std::shared_ptr<Node> arg;
104
    uint32_t line = 0;
105
    AppNode(std::shared_ptr<Node> f, std::shared_ptr<Node> a, uint32_t l = 0);
106
};
107
108
struct BinaryOpNode {
109
    BinaryOp op;
110
    std::shared_ptr<Node> left;
111
    std::shared_ptr<Node> right;
112
    uint32_t line = 0;
113
    BinaryOpNode(BinaryOp o, std::shared_ptr<Node> l, std::shared_ptr<Node> r, uint32_t ln = 0);
114
};
115
116
struct UnaryOpNode {
117
    UnaryOp op;
118
    std::shared_ptr<Node> operand;
119
    uint32_t line = 0;
120
    UnaryOpNode(UnaryOp o, std::shared_ptr<Node> operand, uint32_t l = 0);
121
};
122
123
struct AttrsetNode {
124
    std::vector<std::pair<std::string, std::shared_ptr<Node>>> attrs;
125
    bool recursive = false;
126
    uint32_t line = 0;
127
    AttrsetNode(bool rec = false, uint32_t l = 0) : recursive(rec), line(l) {}
128
};
129
130
struct SelectNode {
131
    std::shared_ptr<Node> expr;
132
    std::shared_ptr<Node> attr;
133
    std::optional<std::shared_ptr<Node>> default_expr;
134
    uint32_t line = 0;
135
    SelectNode(std::shared_ptr<Node> e, std::shared_ptr<Node> a, uint32_t l = 0);
136
};
137
138
struct HasAttrNode {
139
    std::shared_ptr<Node> expr;
140
    std::shared_ptr<Node> attr;
141
    uint32_t line = 0;
142
    HasAttrNode(std::shared_ptr<Node> e, std::shared_ptr<Node> a, uint32_t l = 0);
143
};
144
145
struct WithNode {
146
    std::shared_ptr<Node> attrs;
147
    std::shared_ptr<Node> body;
148
    uint32_t line = 0;
149
    WithNode(std::shared_ptr<Node> a, std::shared_ptr<Node> b, uint32_t l = 0);
150
};
151
152
struct IfNode {
153
    std::shared_ptr<Node> cond;
154
    std::shared_ptr<Node> then_branch;
155
    std::shared_ptr<Node> else_branch;
156
    uint32_t line = 0;
157
    IfNode(std::shared_ptr<Node> c, std::shared_ptr<Node> t, std::shared_ptr<Node> e, uint32_t l = 0);
158
};
159
160
struct LetNode {
161
    std::vector<std::pair<std::string, std::shared_ptr<Node>>> bindings;
162
    std::shared_ptr<Node> body;
163
    uint32_t line = 0;
164
    LetNode(std::shared_ptr<Node> b, uint32_t l = 0);
165
};
166
167
struct LetRecNode {
168
    std::vector<std::pair<std::string, std::shared_ptr<Node>>> bindings;
169
    std::shared_ptr<Node> body;
170
    uint32_t line = 0;
171
    LetRecNode(std::shared_ptr<Node> b, uint32_t l = 0);
172
};
173
174
struct AssertNode {
175
    std::shared_ptr<Node> cond;
176
    std::shared_ptr<Node> body;
177
    uint32_t line = 0;
178
    AssertNode(std::shared_ptr<Node> c, std::shared_ptr<Node> b, uint32_t l = 0);
179
};
180
181
struct ThunkNode {
182
    std::shared_ptr<Node> expr;
183
    uint32_t line = 0;
184
    ThunkNode(std::shared_ptr<Node> e, uint32_t l = 0);
185
};
186
187
struct ForceNode {
188
    std::shared_ptr<Node> expr;
189
    uint32_t line = 0;
190
    ForceNode(std::shared_ptr<Node> e, uint32_t l = 0);
191
};
192
193
// Node wraps a variant for type-safe AST
194
class Node {
195
public:
196
    using Variant = std::variant<
197
        ConstIntNode,
198
        ConstStringNode,
199
        ConstPathNode,
200
        ConstBoolNode,
201
        ConstNullNode,
202
        VarNode,
203
        LambdaNode,
204
        AppNode,
205
        BinaryOpNode,
206
        UnaryOpNode,
207
        AttrsetNode,
208
        SelectNode,
209
        HasAttrNode,
210
        WithNode,
211
        IfNode,
212
        LetNode,
213
        LetRecNode,
214
        AssertNode,
215
        ThunkNode,
216
        ForceNode
217
    >;
218
219
    Variant data;
220
221
    template<typename T>
222
    Node(T&& value) : data(std::forward<T>(value)) {}
223
224
    template<typename T>
225
    T* get_if() { return std::get_if<T>(&data); }
226
227
    template<typename T>
228
    const T* get_if() const { return std::get_if<T>(&data); }
229
230
    template<typename T>
231
    bool holds() const { return std::holds_alternative<T>(data); }
232
};
233
234
// Constructor implementations
235
inline LambdaNode::LambdaNode(uint32_t a, std::shared_ptr<Node> b, uint32_t l)
236
    : arity(a), body(b), line(l) {}
237
238
inline AppNode::AppNode(std::shared_ptr<Node> f, std::shared_ptr<Node> a, uint32_t l)
239
    : func(f), arg(a), line(l) {}
240
241
inline BinaryOpNode::BinaryOpNode(BinaryOp o, std::shared_ptr<Node> l, std::shared_ptr<Node> r, uint32_t ln)
242
    : op(o), left(l), right(r), line(ln) {}
243
244
inline UnaryOpNode::UnaryOpNode(UnaryOp o, std::shared_ptr<Node> operand, uint32_t l)
245
    : op(o), operand(operand), line(l) {}
246
247
inline SelectNode::SelectNode(std::shared_ptr<Node> e, std::shared_ptr<Node> a, uint32_t l)
248
    : expr(e), attr(a), line(l) {}
249
250
inline HasAttrNode::HasAttrNode(std::shared_ptr<Node> e, std::shared_ptr<Node> a, uint32_t l)
251
    : expr(e), attr(a), line(l) {}
252
253
inline WithNode::WithNode(std::shared_ptr<Node> a, std::shared_ptr<Node> b, uint32_t l)
254
    : attrs(a), body(b), line(l) {}
255
256
inline IfNode::IfNode(std::shared_ptr<Node> c, std::shared_ptr<Node> t, std::shared_ptr<Node> e, uint32_t l)
257
    : cond(c), then_branch(t), else_branch(e), line(l) {}
258
259
inline LetNode::LetNode(std::shared_ptr<Node> b, uint32_t l)
260
    : body(b), line(l) {}
261
262
inline LetRecNode::LetRecNode(std::shared_ptr<Node> b, uint32_t l)
263
    : body(b), line(l) {}
264
265
inline AssertNode::AssertNode(std::shared_ptr<Node> c, std::shared_ptr<Node> b, uint32_t l)
266
    : cond(c), body(b), line(l) {}
267
268
inline ThunkNode::ThunkNode(std::shared_ptr<Node> e, uint32_t l)
269
    : expr(e), line(l) {}
270
271
inline ForceNode::ForceNode(std::shared_ptr<Node> e, uint32_t l)
272
    : expr(e), line(l) {}
273
274
struct SourceFile {
275
    std::string path;
276
    std::string content;
277
    std::shared_ptr<Node> ast;
278
};
279
280
struct IRModule {
281
    uint32_t version = IR_VERSION;
282
    std::vector<SourceFile> sources;
283
    std::vector<std::pair<std::string, std::string>> imports;
284
    std::shared_ptr<Node> entry;
285
    std::unordered_map<std::string, uint32_t> string_table;
286
};
287
288
}
289
#endif