alexandru-dinu / igcc

Interactive GCC - C/C++ REPL.
GNU General Public License v3.0
197 stars 12 forks source link
c cpp repl

Interactive GCC

tests contrib Code style: black

[!NOTE] The original repo from Andy Balaam is here: https://codeberg.org/andybalaam/igcc. In this fork, I've done some refactoring and tried to make it easier to use.

[!WARNING] This project is a hacky attempt at getting a shorter feedback loop when working with C/C++ in some cases and it's obviously not intended for anything serious.

Interactive GCC (igcc) is a read-eval-print loop (REPL) for C/C++. It works by manipulating a base source file with user commands, compiles the source after each modification, then executes the resulting binary and collects its stdout & stderr. Multi-line (block) input is supported, so you can add multiple lines in one go and invoke the compiler just once (examples below).

You can include various header files. For convenience, a default header is included: boilerplate.h. Also, using namespace std; is not available by default, but you can explicitly add it (example below).

Various aspects of igcc can be configured, see config.yaml.

Getting started

The easiest way to get started is to use pipx:

pipx install git+https://github.com/alexandru-dinu/igcc.git

Alternatively, you can also just use pip (a dedicated virtual environment is recommended).

Now you can run the REPL with:

igcc

Available args:

$ igcc --help
usage: igcc [-h] [-I INCLUDE [INCLUDE ...]] [-L LIBDIR [LIBDIR ...]] [-l LIB [LIB ...]]

options:
  -h, --help            show this help message and exit
  -I INCLUDE [INCLUDE ...]
                        Add INCLUDE to the list of directories to be searched for header files.
  -L LIBDIR [LIBDIR ...]
                        Add LIBDIR to the list of directories to be searched for library files.
  -l LIB [LIB ...]      Search the library LIB when linking.

The code will be compiled with GCC (g++) and the results (if any) will be displayed. Type .h for help:

$ igcc
[1]> .h
.h  Show this help message
.e  Show the last compile errors/warnings
.l  List the code you have entered
.L  List the whole program as given to the compiler
.r  Redo undone command
.u  Undo previous command
.q  Quit

Examples

$ igcc
[1]> int a = 5;
[2]> a += 2;
[3]> using namespace std;
[4]> cout << a << endl;
7

[5]> int b = 17;
[6]> a *= b;
[7]> cout << a << ", " << b << endl;
119, 17

[8]> .L
#include "boilerplate.h"
using namespace std;

int main(void) {
    int a = 5;
    a += 2;
    cout << a << endl;
    int b = 17;
    a *= b;
    cout << a << ", " << b << endl;

    return 0;
}

Multi-line input is supported (check multiline_marker from config). The benefit is avoiding multiple compiler calls.

$ igcc
[1]> .m
... for (int i = 0; i < 10; i++) {
...   std::cout << i << " ";
... }
... std::cout << "\n";
... .m
0 1 2 3 4 5 6 7 8 9

You can include headers:

$ igcc
[1]> #include <vector>
[2]> std::vector<int> xs{1,2,3};
[3]> xs.push_back(17);
[4]> .m
... for (auto x : xs) {
...   std::cout << x << " ";
... }
... .m
1 2 3 17

Libs can be linked:

$ igcc -lpthread
[  1]> #include <pthread.h>
[  2]> pthread_t thr;
[  3]> const char* msg = "Hello, World!";
[  4]> // assuming print_msg is defined somewhere
[  5]> int ret = pthread_create(&thr, NULL, print_msg, (void*) msg); pthread_join(thr, NULL);
Hello, World!

You can also undo commands:

$ igcc
[1]> int x = 2
 Compile error - type .e to see it

[2]> .e
<stdin>: In function ‘int main()’:
<stdin>:7:5: error: expected ‘,’ or ‘;’ before ‘return’
<stdin>:5:9: warning: unused variable ‘x’ [-Wunused-variable]

[2]> .u
Undone `int x = 2`
[1]> int x = 2;
[2]> .L
#include "boilerplate.h"

int main(void) {
    int x = 2;

    return 0;
}

... or redo previously undone commands:

$ igcc
[1]> int x = 2;
[2]> std::cout << x;
2
[3]> .u
Undone `std::cout << x;`
[2]> .L
#include "boilerplate.h"

int main(void) {
    int x = 2;

    return 0;
}
[2]> .r
Redone `std::cout << x;`
2
[3]> .L
#include "boilerplate.h"

int main(void) {
    int x = 2;
    std::cout << x;

    return 0;
}

Future work

See https://github.com/alexandru-dinu/igcc/issues

Similar projects

Credits