Include data structures for assembler
diff --git a/.gitignore b/.gitignore
index 9f27f48..0443fb7 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,5 +1,6 @@
-.~*
+**/.~*
+**/.#*
 build
-#*#
-*~
-~*
\ No newline at end of file
+**/#*#
+**/*~
+**/~*
\ No newline at end of file
diff --git a/.gitmodules b/.gitmodules
index 747fb4d..6dc59b1 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -1,6 +1,3 @@
 [submodule "nuklear"]
 	path = nuklear
 	url = https://github.com/Immediate-Mode-UI/Nuklear.git
-[submodule "as/libcollect"]
-	path = as/libcollect
-	url = https://github.com/swissChili/libcollect
diff --git a/as/CMakeLists.txt b/as/CMakeLists.txt
index e2062c2..70638fe 100644
--- a/as/CMakeLists.txt
+++ b/as/CMakeLists.txt
@@ -2,8 +2,4 @@
 
 project(6502 VERSION 0.1.0 LANGUAGES C)
 
-subdirs(libcollect)
-include_directories(libcollect/include)
-
-add_executable(6502-as main.c as.h as.c)
-target_link_libraries(6502-as collect)
+add_executable(6502-as main.c as.h as.c map.h map.c hash.c hash.c)
diff --git a/as/as.c b/as/as.c
index 61ad6bd..36d9637 100644
--- a/as/as.c
+++ b/as/as.c
@@ -2,9 +2,8 @@
 #include "../cpu.h"
 #include "../instructions.h"
 #include "../mnemonics.h"
+#include "map.h"
 
-#include <collect/map.h>
-#include <collect/vector.h>
 #include <string.h>
 #include <ctype.h>
 #include <stdbool.h>
@@ -374,10 +373,10 @@
 
 uint32_t assemble(char *code, FILE *out)
 {
-	uintptr_t num_insts = 0;
+	uintptr_t num_insts = 0,
+		pc = 0x600;
 	uint32_t line_no = 1;
-	map *labels = new_map();
-	vector *insts = new_vector();
+	map_t *labels = new_map();
 	char *line;
 
 	printf("Assembling File\n");
@@ -397,14 +396,16 @@
 
 		if (label)
 		{
-			map_set(labels, label, (void *)num_insts);
-			printf("Set label %s at %lu\n", label, num_insts);
+			map_set(labels, label, (void *)pc);
+			printf("Set label %s at %lu\n", label, pc);
 		}
 
 		if (mn)
 		{
 #define MN(a) if (!strcasecmp(mn, #a)) \
+			{						   \
 				mnemonic = a;		   \
+			}						   \
 			else
 
 			MNEMONICS;
@@ -418,6 +419,7 @@
 			if (mnemonic == _mn && parse_arg(line, am, &arg)) \
 			{												  \
 				arg.opcode = op;							  \
+				pc += len;									  \
 				print_inst(&arg);							  \
 			}												  \
 			else
@@ -429,7 +431,6 @@
 #undef INST
 		}
 
-		num_insts++;
 		line = strtok(NULL, "\r\n");
 	}
 
diff --git a/as/hash.c b/as/hash.c
new file mode 100644
index 0000000..df4fec0
--- /dev/null
+++ b/as/hash.c
@@ -0,0 +1,14 @@
+#include "hash.h"
+
+uint32_t hash(char *str)
+{
+    uint32_t hash = 5381;
+    char c;
+
+    while (c = *str++)
+    {
+        hash = (hash << 5) + hash + c;
+    }
+
+    return hash;
+}
diff --git a/as/hash.h b/as/hash.h
new file mode 100644
index 0000000..a1312cd
--- /dev/null
+++ b/as/hash.h
@@ -0,0 +1,9 @@
+#ifndef LIBASM_HASH_H
+#define LIBASM_HASH_H
+
+#include <stdint.h>
+
+uint32_t hash(char *str);
+
+
+#endif
diff --git a/as/libcollect b/as/libcollect
deleted file mode 160000
index e9ee522..0000000
--- a/as/libcollect
+++ /dev/null
@@ -1 +0,0 @@
-Subproject commit e9ee5221d307378150d2119939025b8709da178a
diff --git a/as/map.c b/as/map.c
new file mode 100644
index 0000000..e990af9
--- /dev/null
+++ b/as/map.c
@@ -0,0 +1,208 @@
+#include "map.h"
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+
+#ifdef MAP_DEBUG
+#define MAP_DEBUG_PRINTF printf
+#else
+#define MAP_DEBUG_PRINTF // nothing
+#endif
+
+map_t *new_map_sized(uint64_t size)
+{
+	map_t *m = malloc(sizeof(map_t));
+
+	/*
+	 * Calloc zeroes the memory, which is what we want.
+	 */
+
+	map_node empty = EMPTY_NODE;
+
+	m->items = calloc(size, sizeof(map_node));
+	m->len = MAP_ALLOC_SIZE;
+	m->full = 0;
+
+	for (int i = 0; i < m->len; i++)
+	{
+		m->items[i] = empty;
+	}
+
+	return m;
+}
+
+map_t *new_map()
+{
+	return new_map_sized(MAP_ALLOC_SIZE);
+}
+
+void free_map(map_t *m)
+{
+	free(m->items);
+	free(m);
+}
+
+void free_map_items(map_t *m)
+{
+	for (int i = 0; i < m->len; i++)
+	{
+		if (m->items[i].key != NULL)
+		{
+			free(m->items[i].key);
+			free(m->items[i].val);
+		}
+	}
+	free(m->items);
+	free(m);
+}
+
+void map_set(map_t *m, char *k, void *v)
+{
+	uint64_t h = hash(k);
+	uint32_t i = h % m->len;
+
+	MAP_DEBUG_PRINTF("hash %u i %u\n", h, i);
+
+	m->count++;
+
+	if (m->full++ < m->len)
+	{
+		map_node val =
+				{
+						malloc(strlen(k)),
+						v,
+						1,
+						h,
+				};
+
+		strcpy(val.key, k);
+
+		uint32_t current = i;
+
+		while (MAP_USED_AT(m->items, current))
+		{
+			if (current == m->len - 1)
+			{
+				current = 0;
+			}
+			else
+			{
+				current++;
+			}
+		}
+
+		MAP_DEBUG_PRINTF("Current %d\n", current);
+
+		m->items[current] = val;
+
+		MAP_DEBUG_PRINTF("val %d\n", *(int *) m->items[current].val);
+	}
+	else
+	{
+		/* resize map */
+		map_t *n_m = new_map_sized(m->len * 2);
+
+		for (uint64_t j = 0; j < m->len; j++)
+		{
+			if (!MAP_USED_AT(m->items, j))
+			{
+				continue;
+			}
+
+			uint32_t current = m->items[j].h;
+
+			while (MAP_USED_AT(m->items, current))
+			{
+				if (current == m->len - 1)
+				{
+					current = 0;
+				}
+				else
+				{
+					current++;
+				}
+			}
+
+			n_m->items[current] = m->items[j];
+		}
+
+		free_map(m);
+		m = n_m;
+	}
+}
+
+int map_exists(map_t *m, char *k)
+{
+	uint64_t h = hash(k);
+	uint32_t i = h % m->len;
+
+	uint32_t current = i;
+
+	while (m->items[current].used)
+	{
+		if (strcmp(m->items[current].key, k) == 0)
+		{
+			return 1;
+		}
+
+		if (current >= m->len - 1)
+		{
+			current = 0;
+			MAP_DEBUG_PRINTF("Current reset to 0\n");
+		}
+		else
+		{
+			current++;
+			MAP_DEBUG_PRINTF("Incrementing current\n");
+		}
+	}
+
+	return 0;
+}
+
+void *map_get(map_t *m, char *k)
+{
+	uint64_t h = hash(k);
+	uint32_t i = h % m->len;
+
+	uint32_t current = i;
+
+	MAP_DEBUG_PRINTF("%s should be %s\n", m->items[current].key, k);
+	MAP_DEBUG_PRINTF("streq %d\n", strcmp(m->items[current].key, k));
+
+	MAP_DEBUG_PRINTF("Current get %d\n", current);
+
+	while (strcmp(m->items[current].key, k) != 0)
+	{
+		MAP_DEBUG_PRINTF("While at %d\n", current);
+		if (current >= m->len - 1)
+		{
+			current = 0;
+			MAP_DEBUG_PRINTF("Current reset to 0\n");
+		}
+		else
+		{
+			current++;
+			MAP_DEBUG_PRINTF("Incrementing current\n");
+		}
+	}
+
+	MAP_DEBUG_PRINTF("val %d\n", *(int *) m->items[current].val);
+
+	return m->items[current].val;
+
+	//return 1;
+}
+
+void map_debug(map_t *m)
+{
+	for (int i = 0; i < m->len; i++)
+	{
+		if (m->items[i].val != NULL)
+		{
+			MAP_DEBUG_PRINTF("i = %d, k = %s, v = %d\n",
+							 i, m->items[i].key, *(int *) m->items[i].val);
+		}
+	}
+}
diff --git a/as/map.h b/as/map.h
new file mode 100644
index 0000000..fded428
--- /dev/null
+++ b/as/map.h
@@ -0,0 +1,119 @@
+#pragma once
+
+
+#include <stdint.h>
+#include <stdlib.h>
+#include "hash.h"
+
+/* 1kb seems reasonable doesn't it? */
+#define MAP_ALLOC_SIZE (1 * 1024)
+
+struct map_node
+{
+    char *key;
+    void *val;
+    int used : 1;
+    uint32_t h;
+};
+
+typedef struct map_node map_node;
+
+#define EMPTY_NODE { NULL, NULL, 0, 0 }
+
+/**
+ * @brief A simple hashmap.
+ *
+ * Allocate map with new_map() and free it with free_map(). Items can be added
+ * with map_set() or the MAP_SET() macro. map_exists() can be used to check if
+ * an item exists in the map, map_get() and MAP_GET() can be used to retrieve
+ * items.
+ */
+struct map
+{
+    uint64_t len;
+    map_node *items;
+    uint64_t full;
+    uint64_t count;
+};
+
+typedef struct map map_t;
+
+/**
+ * @deprecated Used map_exists instead
+ */
+#define MAP_USED_AT(m, i) (m[i].used)
+
+/**
+ * @brief Allocate a new map on the heap
+ * @return A pointer to the allocated map
+ */
+map_t *new_map();
+
+/**
+ * @brief Allocate a map on the heap with a specific capacity. Map will be
+ *        reallocated if this capacity is exceeded.
+ * @return A pointer to the allocated map
+ */
+map_t *new_map_sized(uint64_t);
+
+/**
+ * @brief Free a map on the heap
+ * @param m The map to free
+ */
+void free_map(map_t *m);
+
+/**
+ * @brief Free a map and its items
+ * @param m The map to free
+ */
+void free_map_items(map_t *m);
+
+/**
+ * @brief Set a certain value in the map
+ * @param m The map
+ * @param k The key whose value should be changed
+ * @param v The new value
+ */
+void map_set(map_t *m, char *k, void *v);
+
+/**
+ * @brief Get the value in a map by it's key
+ * @param m The map
+ * @param k The key
+ * @return The value at k
+ */
+void *map_get(map_t *m, char *k);
+
+/**
+ * @brief Check if a key is used in a map
+ * @param m The map
+ * @param k The key
+ * @return 1 if the key is used, 0 otherwise
+ */
+int map_exists(map_t *m, char *k);
+
+/**
+ * @brief Print a map's contents to stdout
+ * @warning Should not be used in production
+ * @param m The map
+ */
+void map_debug(map_t *m);
+
+#define MAP_GET(t, m, k) *(t *)map_get(m, k)
+
+/**
+ * @brief Helper macro to allocate memory for a value on the heap and store it
+ *		  at a given key
+ * @warning This is unsafe and should be used with caution, especially for more
+ *			complex types
+ * @param m The map
+ * @param k The key at which to insert the value
+ * @param v The value
+ */
+#define MAP_SET(m, k, v)										 \
+	{															 \
+		__typeof__(v) *__map_temp = malloc(sizeof(__typeof(v))); \
+		*__map_temp = v;										 \
+		map_set(m, k, __map_temp);								 \
+	}
+