diff --git a/.gitignore b/.gitignore
index 140faf9..d35d3fa 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,4 +1,5 @@
 build/
 .vscode/
 vgcore*
-test.*
\ No newline at end of file
+test.*
+a.out
diff --git a/Makefile b/Makefile
index 5111c78..e38386b 100644
--- a/Makefile
+++ b/Makefile
@@ -9,7 +9,7 @@ OBJS := $(SRCS:%=$(BUILD_DIR)/%.o)
 INC_DIRS := $(shell find $(SRC_DIRS) -type d)
 INC_FLAGS := $(addprefix -I,$(INC_DIRS))
 
-CPPFLAGS ?= $(INC_FLAGS) -MMD -MP
+CPPFLAGS ?= $(INC_FLAGS) -MMD -MP -D IO_OPERATIONS
 
 $(BUILD_DIR)/$(TARGET_EXEC): $(OBJS)
 	$(CC) -ggdb3 $(OBJS) -o $@ $(LDFLAGS)
diff --git a/src/compile.c b/src/compile.c
new file mode 100644
index 0000000..40bf4d3
--- /dev/null
+++ b/src/compile.c
@@ -0,0 +1,5 @@
+#include "./compile.h"
+
+int compile(char input[], char output[])
+{
+}
\ No newline at end of file
diff --git a/src/compile.h b/src/compile.h
new file mode 100644
index 0000000..d85c224
--- /dev/null
+++ b/src/compile.h
@@ -0,0 +1,5 @@
+#ifndef COMPILE_H
+
+int compile(char input[], char output[]);
+
+#endif
\ No newline at end of file
diff --git a/src/main.c b/src/main.c
index 78fb974..cdf7ed3 100644
--- a/src/main.c
+++ b/src/main.c
@@ -1,6 +1,82 @@
 #include "./run.h"
 #include "./stack.h"
+#include "./compile.h"
+#include "./read_bin.h"
 
-int main()
+#ifdef IO_OPERATIONS
+#include <stdio.h>
+
+void print_help()
 {
-}
\ No newline at end of file
+  printf("*HELP*\n");
+}
+#endif
+
+int main(int argc, char *argv[])
+{
+  if (argc < 2)
+  {
+#ifdef IO_OPERATIONS
+    fprintf(stderr, "Illegal input: command must be specified\n");
+    print_help();
+#endif
+    return 2;
+  }
+  if (strcmp(argv[1], "build") == 0)
+  {
+    if (argc == 3)
+      compile(argv[2], "out.bin");
+    else if (argc == 4)
+      compile(argv[2], argv[3]);
+    else
+    {
+#ifdef IO_OPERATIONS
+      fprintf(stderr, "Illegal input for build:\n");
+      print_help();
+#endif
+      return 2;
+    }
+  }
+  else if (strcmp(argv[1], "run") == 0)
+  {
+    stack_t *stack;
+
+    int *res = NULL;
+
+    if (argc == 4)
+      stack = stack_new(atoi(argv[3]), res);
+    else if (argc == 3)
+      stack = stack_new(1024, res);
+    else
+    {
+#ifdef IO_OPERATIONS
+      fprintf(stderr, "Illegal input for run:\n");
+      print_help();
+#endif
+      return 2;
+    }
+
+    if (res != NULL && *res == -1)
+    {
+#ifdef IO_OPERATIONS
+      fprintf(stderr, "Stack creation error: check memory usage.\n");
+      print_help();
+#endif
+      return 1;
+    }
+
+    command_t **commands = read_bin_file(argv[2], res);
+    if (commands == NULL)
+      return 1;
+
+    return run(commands, stack);
+  }
+  else
+  {
+#ifdef IO_OPERATIONS
+    fprintf(stderr, "Illegal input: no such command\n");
+    print_help();
+#endif
+    return 2;
+  }
+}
diff --git a/src/read_bin.c b/src/read_bin.c
new file mode 100644
index 0000000..4d7edc3
--- /dev/null
+++ b/src/read_bin.c
@@ -0,0 +1,30 @@
+#include "./read_bin.h"
+
+command_t **read_bin_file(char src[], int *res)
+{
+  FILE *file = fopen(src, "rb");
+  if (file == NULL)
+    return NULL;
+
+  int size = -1;
+  fread(&size, sizeof(int), 1, file);
+
+  command_t **buffer = malloc(sizeof(command_t *) * size);
+  if (buffer == NULL)
+  {
+    *res = -1;
+    return NULL;
+  }
+
+  for (int i = 0; i < size; i++)
+  {
+    buffer[i] = malloc(sizeof(command_t));
+
+    fread(buffer[i]->code, sizeof(int), 1, file);
+
+    buffer[i]->arg_v = malloc(sizeof(int) * cmd_desc[buffer[i]->code].argc);
+    fread(buffer[i]->arg_v, sizeof(int), cmd_desc[buffer[i]->code].argc, file);
+  }
+
+  return buffer;
+}
diff --git a/src/read_bin.h b/src/read_bin.h
new file mode 100644
index 0000000..cc0c80d
--- /dev/null
+++ b/src/read_bin.h
@@ -0,0 +1,10 @@
+#ifndef READ_BIN_H
+
+#include <stdio.h>
+#include <string.h>
+
+#include "./command.h"
+
+command_t **read_bin_file(char src[], int *res);
+
+#endif
\ No newline at end of file