diff --git a/src/ast_interpreter.c b/src/ast_interpreter.c
index 1edde294b1520692cb99f5f59d625942b47f9f63..48f8976d9c0aebdea1b7ce805dfaabbcd6ffc22c 100644
--- a/src/ast_interpreter.c
+++ b/src/ast_interpreter.c
@@ -5,11 +5,11 @@
 #include "parser.h"
 #include "ast_interpreter.h"
 
-bool value_to_bool ( Value value ) {
-  if ( value . kind == VALUE_NULL )
+bool value_to_bool ( Value * value ) {
+  if ( value -> kind == VALUE_NULL )
     return false;
-  if ( value . kind == VALUE_BOOLEAN )
-    return value . boolean;
+  if ( value -> kind == VALUE_BOOLEAN )
+    return ((BoolValue*) value ) -> boolean;
   return true;
 }
 
@@ -31,7 +31,7 @@ void env_pop ( ASTInterpreterState * state ) {
   free (tmp);
 }
 
-void env_put ( ASTInterpreterState * state, Str name, Value value ) {
+void env_put ( ASTInterpreterState * state, Str name, Value * value ) {
   Environment * env = state -> current_env;
   EnvironmentEntry * entry;
   while ( env ) {
@@ -58,11 +58,9 @@ void env_put ( ASTInterpreterState * state, Str name, Value value ) {
   entry = (EnvironmentEntry*) malloc ( sizeof (EnvironmentEntry) );
   (*entry) = (EnvironmentEntry) {.name = name, .value = value, .next = env -> start };
   env -> start = entry;
-  // fprintf ( stderr, "Variable with name %.*s does not exist.\n", (int) name . len, name . str );
-  // exit ( 1 );
 }
 
-void env_def ( ASTInterpreterState * state, Str name, Value value ) {
+void env_def ( ASTInterpreterState * state, Str name, Value * value ) {
   Environment * env = state -> current_env ? state -> current_env : & state -> global_env;
   EnvironmentEntry * parent = NULL;
   EnvironmentEntry * entry = env -> start;
@@ -70,8 +68,6 @@ void env_def ( ASTInterpreterState * state, Str name, Value value ) {
     if ( str_eq ( name, entry -> name ) ) {
       entry -> value = value;
       return;
-      //fprintf ( stderr, "Variable with name %.*s already exists.\n", (int) name . len, name . str );
-      //exit ( 1 );
     }
     parent = entry;
     entry = entry -> next;
@@ -102,9 +98,6 @@ Value env_get ( ASTInterpreterState * state, Str name ) {
       return entry -> value;
     entry = entry -> next;
   }
-  // fprintf ( stderr, "Variable with name %.*s does not exist.\n", (int) name . len, name . str );
-  // exit ( 1 );
-  // return (Value) { .kind = VALUE_NULL };
   env = state -> current_env;
   env = env ? env : & state -> global_env;
   entry = (EnvironmentEntry*) malloc ( sizeof (EnvironmentEntry) );
@@ -113,15 +106,25 @@ Value env_get ( ASTInterpreterState * state, Str name ) {
   return entry -> value;
 }
 
-void * heap_alloc ( Heap * heap, size_t len, size_t align ) {
+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;
+}
 
-  if ( heap -> next >= heap -> end )
-    return NULL;
-  
+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;
@@ -164,6 +167,24 @@ void state_destroy ( ASTInterpreterState * state ) {
   }
 }
 
+NullValue * make_null ( ASTInterpreterState * state ) {
+  NullValue * value = heap_alloc ( state -> heap, sizeof (NullValue) );
+  *value = (NullValue) { .kind = (Value) { .kind = VALUE_NULL } };
+  return value;
+}
+
+IntValue * 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;
+}
+
+BoolValue * 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 * get_base ( Value * object ) {
   Value * curr = object;
   Object * tmp;
@@ -174,7 +195,7 @@ Value * get_base ( Value * object ) {
   return curr;
 }
 
-Value try_operator ( Value object, Value * arguments, size_t argc, Str * name ) {
+Value * try_operator ( Value object, Value * arguments, size_t argc, Str * name ) {
   switch ( object . kind ) {
     case VALUE_INTEGER: {
       if ( argc != 1 ) {
@@ -267,19 +288,17 @@ Value try_operator ( Value object, Value * arguments, size_t argc, Str * name )
     default:
       break;
   }
-  //fprintf ( stderr, "Method %.*s does not exist.\n", (int) name -> len, name -> str );
-  //exit ( 13 );
-  return (Value) { .kind = VALUE_INVALID };
+  return NULL;
 }
 
-Value function_call ( ASTInterpreterState * state, Value callee, bool is_function, Ast ** arguments, size_t argc, Str * name ) {
+Value function_call ( ASTInterpreterState * state, Value * callee, bool is_function, Ast ** arguments, size_t argc, Str * name ) {
   Value * values = (Value *) malloc ( argc * sizeof (Value) );
   for ( size_t i = 0; i < argc; ++i )
     values [ i ] = evaluate ( state, arguments [ i ] );
-  Value ret = (Value) { .kind = VALUE_NULL };
-  Value function = callee;
+  Value * ret = NULL;
+  Value * function = callee;
   if ( ! is_function ) {
-    function = (Value) { .kind = VALUE_NULL };
+    function = NULL;
     Value * next = &callee;
     Value * curr;
     Object * tmp;
@@ -297,18 +316,11 @@ Value function_call ( ASTInterpreterState * state, Value callee, bool is_functio
     if ( function . kind == VALUE_NULL ) {
       curr = &callee;
       Value * base = get_base ( &callee );
-      //while ( curr ) {
       ret = try_operator ( *base, values, argc, name );
-      if ( ret . kind != VALUE_INVALID ) {
+      if ( ! ret ) {
         free ( values );
         return ret;
       }
-      //  if ( curr -> kind == VALUE_OBJECT ) {
-      //    tmp = (Object *) curr -> address;
-      //    curr = &tmp -> extends;
-      //  } else 
-      //    break;
-      //}
       free ( values );
       fprintf ( stderr, "Method %.*s does not exist for this object and/or arguments.\n", (int) name -> len, name -> str );
       exit ( 13 );
@@ -318,20 +330,19 @@ Value function_call ( ASTInterpreterState * state, Value callee, bool is_functio
     exit ( 4 );
   }
   Environment * tmp;
-  //if ( is_function ) {
-    tmp = state -> current_env;
-    state -> current_env = NULL;
-  //}
+  tmp = state -> current_env;
+  state -> current_env = NULL;
   env_push ( state );
-  env_def ( state, STR ("this"), is_function ? (Value) { .kind = VALUE_NULL } : callee );
+  env_def ( state, STR ("this"), is_function ? make_null ( state ) : callee );
   for ( size_t i = 0; i < argc; ++i )
     env_def ( state, function . function -> parameters [ i ], values [ i ] );
   ret = evaluate ( state, function . function -> body );
   env_pop ( state );
-  //if ( is_function )
-    state -> current_env = tmp;
+  state -> current_env = tmp;
   
   free ( values );
+  if ( ! ret )
+    ret = make_null ( state );
   return ret;
 }
 
@@ -403,7 +414,7 @@ void print_value ( Value value ) {
   }
 }
 
-void fml_print ( Str format, Value * args, size_t argc ) {
+void fml_print ( Str format, Value ** args, size_t argc ) {
   u8 c;
   size_t arg = 0;
   for ( size_t i = 0; i < format . len; ++i ) {
@@ -448,19 +459,19 @@ void fml_print ( Str format, Value * args, size_t argc ) {
 Value evaluate ( ASTInterpreterState * state, Ast * ast ) {
   switch ( ast -> kind ) {
     case AST_INTEGER:
-      return (Value) { .kind = VALUE_INTEGER, .integer = ((AstInteger*) ast ) -> value };
+      return make_int ( state, ((AstInteger*) ast ) -> value );
     case AST_BOOLEAN:
-      return (Value) { .kind = VALUE_BOOLEAN, .boolean = ((AstBoolean*) ast ) -> value };
+      return make_int ( state, ((AstBoolean*) ast ) -> value );
     case AST_NULL:
-      return (Value) { .kind = VALUE_NULL };
+      return make_null ( state );
     case AST_PRINT: {
       AstPrint * printAst = (AstPrint*) ast;
-      Value * args = (Value *) malloc ( sizeof (Value) * printAst -> argument_cnt );
+      Value ** args = (Value **) malloc ( sizeof (Value*) * printAst -> argument_cnt );
       for ( size_t i = 0; i < printAst -> argument_cnt; ++i ) 
         args [ i ] = evaluate ( state, printAst -> arguments [ i ] );
       fml_print ( printAst -> format, args, printAst -> argument_cnt );
       free ( args );
-      return (Value) { .kind = VALUE_NULL };
+      return make_null ( state );
     }
     case AST_TOP: {
       AstTop * topAst = (AstTop*) ast;
@@ -509,10 +520,12 @@ Value evaluate ( ASTInterpreterState * state, Ast * ast ) {
         evaluate ( state, loopAst -> body );
         env_pop ( state );
       }
-      return (Value) { .kind = VALUE_NULL };
+      return (NullValue) { .kind = (Value) { .kind = VALUE_NULL } };
     }
     case AST_FUNCTION:
-      return (Value) { .kind = VALUE_FUNCTION, .function = (AstFunction*) ast };
+      FunctionValue * value = heap_alloc ( state -> heap, sizeof (FunctionValue) );
+      *value = (FunctionValue) { .kind = (Value) { .kind = VALUE_FUNCTION }, .function = (AstFunction*) ast };
+      return *value;
     case AST_FUNCTION_CALL: {
       AstFunctionCall * callAst = (AstFunctionCall*) ast;
       Value function = evaluate ( state, callAst -> function );
@@ -534,7 +547,7 @@ Value evaluate ( ASTInterpreterState * state, Ast * ast ) {
         fprintf ( stderr, "Invalid array size.\n" );
         exit ( 5 );
       }
-      Value * addr = (Value*) heap_alloc ( state -> heap, sizeof (Value) * (size . integer + 1), alignof (Value) );
+      Value * addr = (Value*) heap_alloc ( state -> heap, sizeof (ArrayValue) + sizeof (Value) * (size . integer) );
       addr [ 0 ] = (Value) { .kind = VALUE_INTEGER, .integer = size . integer };
       for ( i32 i = 1; i <= size . integer; ++i ) {
         env_push ( state );
@@ -562,10 +575,10 @@ Value evaluate ( ASTInterpreterState * state, Ast * ast ) {
     case AST_OBJECT: {
       AstObject * objAst = (AstObject*) ast;
       Value extends = evaluate ( state, objAst -> extends );
-      Object * addr = (Object*) heap_alloc ( state -> heap, sizeof (Object), alignof (Object) );
+      Object * addr = (Object*) heap_alloc ( state -> heap, sizeof (Object) );
       addr -> member_cnt = objAst -> member_cnt;
       addr -> extends = extends;
-      addr -> members = (SimpleEntry*) heap_alloc ( state -> heap, sizeof (SimpleEntry) * addr -> member_cnt, alignof (SimpleEntry) );
+      addr -> members = (SimpleEntry*) heap_alloc ( state -> heap, sizeof (SimpleEntry) * addr -> member_cnt );
       Value value;
       AstDefinition * defAst;
       for ( size_t i = 0; i < addr -> member_cnt; ++i ) {
@@ -574,9 +587,9 @@ Value evaluate ( ASTInterpreterState * state, Ast * ast ) {
           exit ( 7 );
         }
         defAst = (AstDefinition*) objAst -> members [ i ];
-        env_push ( state );
-        value = evaluate ( state, objAst -> members [ i ] );
-        env_pop ( state );
+        //env_push ( state );
+        value = evaluate ( state, defAst -> value );
+        //env_pop ( state );
         addr -> members [ i ] . name  = defAst -> name;
         addr -> members [ i ] . value = value;
       }
diff --git a/src/ast_interpreter.h b/src/ast_interpreter.h
index 2c92701220a374115875659f2f8c5a23b3f0f6ea..17d3df0f4645c03e95236c7618de7056aab78212 100644
--- a/src/ast_interpreter.h
+++ b/src/ast_interpreter.h
@@ -16,6 +16,51 @@ typedef struct Heap {
   u8 * end;
 } Heap;
 
+typedef struct Value {
+  ValueType kind;
+} Value;
+
+typedef struct Object {
+  struct Value * extends;
+  size_t member_cnt;
+  SimpleEntry members [];
+} Object;
+
+typedef struct Array {
+  i32 length;
+  Value * members [];
+} Array;
+
+typedef struct NullValue {
+  Value kind;
+} NullValue;
+
+typedef struct IntValue {
+  Value kind;
+  i32 integer;
+} IntValue;
+
+typedef struct BoolValue {
+  Value kind;
+  bool boolean;
+} BoolValue;
+
+typedef struct FunctionValue {
+  Value kind;
+  AstFunction * function;
+} FunctionValue;
+
+typedef struct ObjectValue {
+  Value kind;
+  Object obj;
+} ObjectValue;
+
+typedef struct ArrayValue {
+  Value kind;
+  Array obj;
+} ArrayValue;
+
+/*
 typedef struct Value {
   ValueType kind;
   union {
@@ -25,22 +70,17 @@ typedef struct Value {
     void * address;
   };
 } Value;
+*/
 
 typedef struct SimpleEntry {
   Str name;
-  Value value;
+  Value * value;
 } SimpleEntry;
 
-typedef struct Object {
-  struct Value extends;
-  size_t member_cnt;
-  SimpleEntry * members;
-} Object;
-
 typedef struct EnvironmentEntry {
   struct EnvironmentEntry * next;
   Str name;
-  Value value;
+  Value * value;
 } EnvironmentEntry;
 
 typedef struct Environment {
@@ -54,25 +94,30 @@ typedef struct ASTInterpreterState {
   Environment * current_env;
 } ASTInterpreterState;
 
-bool value_to_bool ( Value value );
+bool value_to_bool ( Value * value );
 
 void env_push ( ASTInterpreterState * state );
 void env_pop ( ASTInterpreterState * state );
-Value env_get ( ASTInterpreterState * state, Str name );
-void env_put ( ASTInterpreterState * state, Str name, Value value );
-void env_def ( ASTInterpreterState * state, Str name, Value value );
-void * heap_alloc ( Heap * heap, size_t len, size_t align );
+Value * env_get ( ASTInterpreterState * state, Str name );
+void env_put ( ASTInterpreterState * state, Str name, Value * value );
+void env_def ( ASTInterpreterState * state, Str name, Value * value );
+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 );
 void state_init ( ASTInterpreterState * state, Heap * heap );
 void state_destroy ( ASTInterpreterState * state );
 
+NullValue * make_null ( ASTInterpreterState * state );
+IntValue * make_int ( ASTInterpreterState * state, i32 val );
+BoolValue * make_bool ( ASTInterpreterState * state, bool val );
+
 Value * get_base ( Value * object );
 Value * get_object_field (Value * object, Str name );
-Value try_operator ( Value object, Value * arguments, size_t argc, Str * name );
-Value function_call ( ASTInterpreterState * state, Value callee, bool is_function, Ast ** arguments, size_t argc, Str * name );
+Value * try_operator ( Value object, Value * arguments, size_t argc, Str * name );
+Value * function_call ( ASTInterpreterState * state, Value * callee, bool is_function, Ast ** arguments, size_t argc, Str * name );
 void print_value ( Value value );
 void fml_print ( Str format, Value * args, size_t argc );
-Value evaluate ( ASTInterpreterState * state, Ast * ast );
+Value * evaluate ( ASTInterpreterState * state, Ast * ast );
 
 int compare_entry ( const void * a, const void * b );
\ No newline at end of file