brewery
notashelf /
554f7f21f155dced1b020f0655cd4f2a320c0ab4

nixir

public

Import-resolving Nix IR plugin

Star0tarball
clone
ssh://git@git.notashelf.dev:33/notashelf/nixir.git
src/irc/main.cppCpp150 lines3.5 KB
1
#include "ir_gen.h"
2
#include "parser.h"
3
#include "resolver.h"
4
#include "serializer.h"
5
#include <cstring>
6
#include <iostream>
7
#include <string>
8
#include <vector>
9
10
namespace nix_irc {
11
12
void print_usage(const char* prog) {
13
  std::cout << "Usage: " << prog << " [options] <input.nix> [output.nixir]\n"
14
            << "\nOptions:\n"
15
            << "  -I <path>    Add search path for imports\n"
16
            << "  --no-imports Disable import resolution\n"
17
            << "  --help       Show this help\n";
18
}
19
20
int run_compile(int argc, char** argv) {
21
  std::string input_file;
22
  std::string output_file;
23
  std::vector<std::string> search_paths;
24
  bool resolve_imports = true;
25
26
  int i = 1;
27
  while (i < argc) {
28
    std::string arg = argv[i];
29
    if (arg == "-I") {
30
      if (i + 1 >= argc) {
31
        std::cerr << "Error: -I requires a path argument\n";
32
        return 1;
33
      }
34
      search_paths.push_back(argv[++i]);
35
    } else if (arg == "--no-imports") {
36
      resolve_imports = false;
37
    } else if (arg == "--help" || arg == "-h") {
38
      print_usage(argv[0]);
39
      return 0;
40
    } else if (arg[0] != '-') {
41
      input_file = arg;
42
      if (i + 1 < argc && argv[i + 1][0] != '-') {
43
        output_file = argv[++i];
44
      }
45
    } else {
46
      std::cerr << "Unknown option: " << arg << "\n";
47
      print_usage(argv[0]);
48
      return 1;
49
    }
50
    i++;
51
  }
52
53
  if (input_file.empty()) {
54
    std::cerr << "Error: No input file specified\n";
55
    print_usage(argv[0]);
56
    return 1;
57
  }
58
59
  if (output_file.empty()) {
60
    output_file = input_file + "ir";
61
  }
62
63
  try {
64
    Parser parser;
65
    Resolver resolver;
66
67
    for (const auto& path : search_paths) {
68
      resolver.add_search_path(path);
69
    }
70
71
    std::cout << "Parsing: " << input_file << "\n";
72
    auto ast = parser.parse_file(input_file);
73
74
    if (!ast) {
75
      std::cerr << "Error: Failed to parse input\n";
76
      return 1;
77
    }
78
79
    std::cout << "Resolving imports...\n";
80
81
    IRGenerator ir_gen;
82
83
    std::cout << "Generating IR...\n";
84
    auto ir = ir_gen.generate(ast);
85
86
    IRModule module;
87
    module.version = IR_VERSION;
88
    module.entry = ir;
89
90
    std::cout << "Serializing to: " << output_file << "\n";
91
    Serializer serializer;
92
    serializer.serialize(module, output_file);
93
94
    std::cout << "Done!\n";
95
    return 0;
96
97
  } catch (const std::exception& e) {
98
    std::cerr << "Error: " << e.what() << "\n";
99
    return 1;
100
  }
101
}
102
103
void print_decompile_usage(const char* prog) {
104
  std::cout << "Usage: " << prog << " decompile <input.nixir>\n";
105
}
106
107
int run_decompile(int argc, char** argv) {
108
  if (argc < 3) {
109
    print_decompile_usage(argv[0]);
110
    return 1;
111
  }
112
113
  std::string input_file = argv[2];
114
115
  try {
116
    Deserializer deserializer;
117
    auto module = deserializer.deserialize(input_file);
118
119
    std::cout << "IR Version: " << module.version << "\n";
120
    std::cout << "Sources: " << module.sources.size() << "\n";
121
    std::cout << "Imports: " << module.imports.size() << "\n";
122
123
    return 0;
124
  } catch (const std::exception& e) {
125
    std::cerr << "Error: " << e.what() << "\n";
126
    return 1;
127
  }
128
}
129
130
} // namespace nix_irc
131
132
int main(int argc, char** argv) {
133
  if (argc < 2) {
134
    nix_irc::print_usage(argv[0]);
135
    return 1;
136
  }
137
138
  std::string cmd = argv[1];
139
140
  if (cmd == "compile" || cmd == "c") {
141
    return nix_irc::run_compile(argc - 1, argv + 1);
142
  } else if (cmd == "decompile" || cmd == "d") {
143
    return nix_irc::run_decompile(argc, argv);
144
  } else if (cmd == "help" || cmd == "--help" || cmd == "-h") {
145
    nix_irc::print_usage(argv[0]);
146
    return 0;
147
  } else {
148
    return nix_irc::run_compile(argc, argv);
149
  }
150
}