diff --git a/src/bc_interpreter.c b/src/bc_interpreter.c
new file mode 100644
index 0000000000000000000000000000000000000000..36cc6971347b7c281eaa6fc9fb6d40bf0734ad01
--- /dev/null
+++ b/src/bc_interpreter.c
@@ -0,0 +1,89 @@
+#include <stdio.h>
+#include <inttypes.h>
+#include <assert.h>
+
+#include "bc_interpreter.h"
+
+// void * heap_alloc_alligned ( Heap * heap, size_t len, size_t align ) {
+//   size_t pos = (size_t) heap -> next;
+//   size_t rem = pos % align;
+//   if ( rem )
+//     heap -> next = heap -> next + align - rem;
+//   if ( heap -> next + len >= heap -> end )
+//     return NULL;  
+//   void * ret = heap -> next;
+//   heap -> next += len;
+//   return ret;
+// }
+// 
+// void * heap_alloc ( Heap * heap, size_t len ) {
+//   size_t pos = (size_t) heap -> next;
+//   size_t rem = pos % 8;
+//   if ( rem )
+//     heap -> next = heap -> next + 8 - rem;
+//   if ( heap -> next + len >= heap -> end )
+//     return NULL;  
+//   void * ret = heap -> next;
+//   heap -> next += len;
+//   return ret;
+// }
+// 
+// void heap_init ( Heap * heap, size_t heap_size ) {
+//   heap -> begin = (u8*) malloc ( heap_size );
+//   heap -> next = heap -> begin;
+//   heap -> end = heap -> begin + heap_size;
+// }
+// 
+// void heap_destroy ( Heap * heap ) {
+//   free ( heap -> begin );
+// }
+
+//Value * make_null ( ASTInterpreterState * state ) {
+//  NullValue * value = heap_alloc ( state -> heap, sizeof (NullValue) );
+//  *value = (NullValue) { .kind = (Value) { .kind = VALUE_NULL } };
+//  return (Value*) value;
+//}
+//
+//Value * make_int ( ASTInterpreterState * state, i32 val ) {
+//  IntValue * value = heap_alloc ( state -> heap, sizeof (IntValue) );
+//  *value = (IntValue) { .kind = (Value) { .kind = VALUE_INTEGER }, .integer = val };
+//  return (Value*) value;
+//}
+//
+//Value * make_bool ( ASTInterpreterState * state, bool val ) {
+//  BoolValue * value = heap_alloc ( state -> heap, sizeof (BoolValue) );
+//  *value = (BoolValue) { .kind = (Value) { .kind = VALUE_BOOLEAN }, .boolean = val };
+//  return (Value*) value;
+//}
+
+static inline u8 read_byte ( Str str, size_t * pos ) {
+  return str . str [ *pos++ ];
+}
+
+void read_header ( Str input, size_t * pos ) {
+  u8 bytes [4];
+  for ( size_t i = 0; i < 4; ++i ) 
+    bytes [ i ] = read_byte ( input, pos );
+  Str header;
+  header . str = bytes;
+  header . len = 4;
+  assert ( str_eq ( header, STR ( "FML\n" ) ) );
+}
+
+Constant * read_constant_pool ( Str input, size_t * pos ) {
+  u8 count_bytes [ 2 ] = { read_byte ( input, pos ), read_byte ( input, pos ) };
+  uint16_t elements = count_bytes [ 1 ] << 8 | count_bytes [ 0 ];
+  printf ( "%u", elements );
+  return NULL;
+}
+
+Program parse_program ( Str input ) {
+  Program program;
+  // read + check header
+  size_t pos = 0;
+  read_header ( input, &pos );
+  // read constant pool 
+  program . constant_pool = read_constant_pool ( input, &pos );
+
+  return program;
+}
diff --git a/src/bc_interpreter.h b/src/bc_interpreter.h
new file mode 100644
index 0000000000000000000000000000000000000000..97102aa2007a2bbf421efd10fc23fcdcb605586b
--- /dev/null
+++ b/src/bc_interpreter.h
@@ -0,0 +1,47 @@
+#pragma once
+#include "parser.h"
+#include "heap.h"
+
+//#define READ_BYTE(str,pos) str . str [ *pos++ ]
+
+typedef enum {
+  CONSTANT_INTEGER,
+  CONSTANT_BOOLEAN,
+  CONSTANT_NULL,
+  CONSTANT_STRING,
+  // VALUE_FUNCTION,
+  // VALUE_ARRAY,
+  // VALUE_OBJECT,
+  // VALUE_INVALID
+} ConstantType;
+
+typedef struct Constant {
+  ConstantType kind;
+  union {
+    i32 integer;
+    bool boolean;
+    Str string;
+  };
+} Constant;
+
+typedef struct Program {
+  Constant * constant_pool;
+  //uint32_t * globals;
+  //size_t entry_point;
+} Program;
+
+// void * heap_alloc_alligned ( Heap * heap, size_t len, size_t align );
+// void * heap_alloc ( Heap * heap, size_t len );
+// void heap_init ( Heap * heap, size_t heap_size );
+// void heap_destroy ( Heap * heap );
+// Value * make_null ( ASTInterpreterState * state );
+// Value * make_int ( ASTInterpreterState * state, i32 val );
+// Value * make_bool ( ASTInterpreterState * state, bool val );
+
+//inline u8 read_byte ( Str str, size_t * pos );
+
+void read_header ( Str input, size_t * pos );
+Constant * read_constant_pool ( Str input, size_t * pos );
+Program parse_program ( Str input );
+//int bc_interpret ( Str input, ... );
+