Nandakumar Edamana
Promotional poster with the text 'Vara: Minimalist digital painting'
Share on:
@ R t f

nguigen

A full-fledged programming language and compiler that generates output in multiple programming languages including C, C++, JavaScript and PHP. It can also act as a zero-overhead GUI code generator, having support for GTK, Qt, HTML5 DOM, etc. Although still under active development, it has started to compile itself.

Examples


Select Example:

Memory Management Example

An example that shows how nguigen makes memory management simple and safe without any runtime overhead unlike in garbage collection. The actions automated by nguigen are:

  • malloc() error check
  • Destruction and de-allocation of a local object
  • Destruction and de-allocation of member object
  • Setting invalid pointers back to NULL

Note: future versions of nguigen might allocate local objects in stack.

ngg input:
// 2022-07-02

class Person
  own name mstring;
;

fun $main
  local person new Person;
;
C output:
typedef struct Person {
	char * name;
} Person;

void person_construct(Person *this)
{
	this->name = NULL;
}

void person_destruct(Person *this)
{
	if(this->name) {
		free(this->name);
	}

	this->name = NULL;
}

int main(int argc, char * argv[])
{

	Person * person = malloc(sizeof(Person));
	if(person == NULL) { perror(NULL); exit(EXIT_FAILURE); }
	person_construct(person);
	person_destruct(person);
	free(person);
	person = NULL;
}

GUI Example

The following code shows how declarative nguigen is when it comes to GUI programming, even if it's still under active development. By the way, please keep in mind that nguigen has grown into a full-fledged programming language, whose expressiveness or safety features are not displayed here yet.


Select:
// 2021-10-27

include gui;

class helloapp
  fun $construct
    wid wnd mainwindow given [ title 'Hello App', ondestroy gui-quit ]
      wid vbx vbox
        wid btn button given [ label 'Click to Close', onclick on-btn-close ];
      ;
    ;
  ;
;

lis on-btn-close for click of button
  =gui-quit;
;

fun $main
  =gui-init;
  
  new helloapp;
  
  =gui-run;
;
// Some stray code and boilerplate have been removed manually.
// The stray code will soon go away, although it never affects compilation or
// performance. 

// hello.c:

void gui_quit()
{
	gtk_main_quit();
}

void helloapp_construct(helloapp * this )
{
	GtkWindow * wnd ;
	wnd = ((GtkWindow * ) gtk_window_new(GTK_WINDOW_TOPLEVEL));
	gtk_window_set_title(wnd, "Hello App");
	g_signal_connect(wnd, "destroy", G_CALLBACK(gui_quit), NULL);
	GtkBox * vbx ;
	vbx = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
	gtk_container_add(GTK_CONTAINER((GtkWidget *) wnd), GTK_WIDGET(vbx));
	GtkButton * btn ;
	btn = ((GtkButton * ) gtk_button_new());
	gtk_container_add(GTK_CONTAINER((GtkWidget *) vbx), GTK_WIDGET(btn));
	gtk_button_set_label(btn, "Click to Close");
	g_signal_connect((GtkWidget *) btn, "clicked", G_CALLBACK(on_btn_close), this);
	gtk_widget_show(((GtkWidget * ) btn));
	gtk_widget_show(((GtkWidget * ) vbx));
	gtk_widget_show(((GtkWidget * ) wnd));
}

void on_btn_close(GtkButton * widget , void * user_data)
{
	gui_quit();
}

int main(int argc, char * argv[])
{
	gtk_init(0, NULL);

	helloapp * _ngg_tmp_0 = malloc(sizeof(helloapp));
	if(_ngg_tmp_0 == NULL) { perror(NULL); exit(EXIT_FAILURE); }
	helloapp_construct(_ngg_tmp_0);
	_ngg_tmp_0;
	gtk_main();
}

// hello.h:

typedef struct helloapp {
} helloapp;

void gui_init();
void gui_run();
void gui_quit();
void helloapp_construct(helloapp * this );
void on_btn_close(GtkButton * widget , void * user_data);
int main(int argc, char * argv[]);
// Some stray code and boilerplate have been removed manually.
// The stray code will soon go away, although it never affects compilation or
// performance. 

// hello.cc:

void gui_quit()
{
  exit(0);
}

void ngg_qt_button_set_onclick(QPushButton * button , void (* callback)(QPushButton * widget , void * user_data), void * womb)
{
  QObject::connect(button, &QPushButton::clicked, [=]() {
    callback(button, womb);
  });
}

helloapp::helloapp()
{
  QMainWindow * wnd ;
  wnd = new QMainWindow();
  wnd->setWindowTitle("Hello App");
  QVBoxLayout * vbx ;
  vbx = new QVBoxLayout();
  QWidget * __ngg_tmp_0_tmp_centwid  = new QWidget();
  wnd->setCentralWidget(__ngg_tmp_0_tmp_centwid);
  __ngg_tmp_0_tmp_centwid->setLayout(vbx);
  QPushButton * btn ;
  btn = new QPushButton();
  vbx->addWidget(btn);
  btn->setText("Click to Close");
  ngg_qt_button_set_onclick(btn, on_btn_close, this);
  btn->setVisible(true);
  wnd->setVisible(true);
}

void on_btn_close(QPushButton * widget , void * user_data)
{
  gui_quit();
}

int main(int argc, char * argv[])
{
  QApplication * _ngg_qapp = new QApplication(argc, argv);
  new helloapp();
  _ngg_qapp->exec();
}

// hello.h:

class helloapp {
public:
 helloapp();
};

void gui_init();
void gui_run();
void gui_quit();
void gui_lis_hdr_button_click(QPushButton * widget , void * user_data);
void ngg_qt_button_set_onclick(QPushButton * button , void (* callback)(QPushButton * widget , void * user_data), void * womb);
void on_btn_close(QPushButton * widget , void * user_data);
int main(int argc, char * argv[]);
Screenshot of a window with a button that says 'Click to Close'
The C-GTK version
Screenshot of a window with a button that says 'Click to Close'
The C++-Qt version

Paper

Click here for Nandakumar's original term paper from 2019 that presented the basic concept and a crude implementation. The current version of nguigen has the same goals, but the implementation is totally different and has grown a lot in terms of capability and maturity.