brewery
notashelf /
32f74c29fdcbe6362c2f8d5f29e38460fe2b8ec2

nixir

public

Import-resolving Nix IR plugin

Star0tarball
clone
ssh://git@git.notashelf.dev:33/notashelf/nixir.git
src/irc/main.cppCpp150 lines4.0 KB
1
#include <iostream>
2
#include "parser.h"
3
#include "resolver.h"
4
#include "ir_gen.h"
5
#include "serializer.h"
6
#include <string>
7
#include <vector>
8
#include <cstring>
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 + "r";
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
}
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
}