brewery
notashelf /
3dd2d604ce6ca911399e13a1f89f4acc3ee2de37

nixir

public

Import-resolving Nix IR plugin

Star0tarball
clone
ssh://git@git.notashelf.dev:33/notashelf/nixir.git
src/plugin.cppCpp145 lines3.6 KB
1
#ifdef unix
2
#undef unix
3
#endif
4
5
#include "nix/expr/eval.hh"
6
#include "nix/expr/primops.hh"
7
#include "nix/expr/value.hh"
8
9
#include "irc/evaluator.h"
10
#include "irc/ir_gen.h"
11
#include "irc/parser.h"
12
#include "irc/serializer.h"
13
#include "irc/types.h"
14
15
#include <iostream>
16
17
namespace nix_ir_plugin {
18
19
using namespace nix;
20
using namespace nix_irc;
21
22
/**
23
 * Load and evaluate a pre-compiled IR bundle
24
 * Usage: builtins.nixIR.loadIR "/path/to/file.nixir"
25
 */
26
static void prim_loadIR(EvalState& state, const PosIdx pos, Value** args, Value& v) {
27
  auto path = state.forceStringNoCtx(
28
      *args[0], pos, "while evaluating the first argument to builtins.nixIR.loadIR");
29
30
  std::string pathStr(path);
31
32
  Deserializer deserializer;
33
  IRModule module;
34
35
  try {
36
    module = deserializer.deserialize(pathStr);
37
  } catch (const std::exception& e) {
38
    state.error<EvalError>("failed to deserialize IR bundle: %s", e.what()).atPos(pos).debugThrow();
39
  }
40
41
  if (!module.entry) {
42
    state.error<EvalError>("IR bundle has no entry point").atPos(pos).debugThrow();
43
  }
44
45
  try {
46
    Evaluator evaluator(state);
47
    evaluator.eval_to_nix(module.entry, v);
48
  } catch (const std::exception& e) {
49
    state.error<EvalError>("failed to evaluate IR: %s", e.what()).atPos(pos).debugThrow();
50
  }
51
}
52
53
/**
54
 * Compile Nix source to IR on-the-fly
55
 * Usage: builtins.nixIR.compile "{ x = 1; }"
56
 */
57
static void prim_compileNix(EvalState& state, const PosIdx pos, Value** args, Value& v) {
58
  auto source = state.forceStringNoCtx(
59
      *args[0], pos, "while evaluating the first argument to builtins.nixIR.compile");
60
61
  std::string sourceStr(source);
62
63
  try {
64
    Parser parser;
65
    auto ast = parser.parse(sourceStr, "<inline>");
66
67
    if (!ast) {
68
      state.error<EvalError>("failed to parse Nix expression").atPos(pos).debugThrow();
69
    }
70
71
    IRGenerator ir_gen;
72
    auto ir = ir_gen.generate(ast);
73
74
    Evaluator evaluator(state);
75
    evaluator.eval_to_nix(ir, v);
76
77
  } catch (const std::exception& e) {
78
    state.error<EvalError>("IR compilation failed: %s", e.what()).atPos(pos).debugThrow();
79
  }
80
}
81
82
/**
83
 * Get information about the IR plugin
84
 * Usage: builtins.nixIR.info
85
 */
86
static void prim_info(EvalState& state, const PosIdx pos, Value** args, Value& v) {
87
  auto bindings = state.buildBindings(3);
88
89
  Value* vName = state.allocValue();
90
  vName->mkString("nix-ir-plugin");
91
  bindings.insert(state.symbols.create("name"), vName);
92
93
  Value* vVersion = state.allocValue();
94
  vVersion->mkString("0.1.0");
95
  bindings.insert(state.symbols.create("version"), vVersion);
96
97
  Value* vStatus = state.allocValue();
98
  vStatus->mkString("runtime-active");
99
  bindings.insert(state.symbols.create("status"), vStatus);
100
101
  v.mkAttrs(bindings.finish());
102
}
103
104
// Register primops on plugin load
105
static RegisterPrimOp rp_loadIR({
106
    .name = "__nixIR_loadIR",
107
    .args = {"path"},
108
    .arity = 1,
109
    .doc = R"(
110
      Load a pre-compiled IR bundle from the given path.
111
      Returns an attrset with information about the loaded bundle.
112
113
    )",
114
    .fun = prim_loadIR,
115
});
116
117
static RegisterPrimOp rp_compileNix({
118
    .name = "__nixIR_compile",
119
    .args = {"source"},
120
    .arity = 1,
121
    .doc = R"(
122
      Compile Nix source code to IR on-the-fly.
123
      Returns an attrset with information about the compiled IR.
124
125
    )",
126
    .fun = prim_compileNix,
127
});
128
129
static RegisterPrimOp rp_info({
130
    .name = "__nixIR_info",
131
    .args = {},
132
    .arity = 0,
133
    .doc = R"(
134
      Get information about the IR plugin.
135
      Returns an attrset with plugin name, version, and status.
136
    )",
137
    .fun = prim_info,
138
});
139
140
} // namespace nix_ir_plugin
141
142
// Plugin initialization message
143
__attribute__((constructor)) static void init_plugin() {
144
  std::cerr << "nix-ir-plugin loaded" << std::endl;
145
}