diff --git a/.idea/runConfigurations/picoc.xml b/.idea/runConfigurations/picoc.xml
new file mode 100644
index 0000000..fc5a4d9
--- /dev/null
+++ b/.idea/runConfigurations/picoc.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/runConfigurations/picoc_basic_c.xml b/.idea/runConfigurations/picoc_basic_c.xml
new file mode 100644
index 0000000..4d9b85e
--- /dev/null
+++ b/.idea/runConfigurations/picoc_basic_c.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/runConfigurations/picoc_complete_c.xml b/.idea/runConfigurations/picoc_complete_c.xml
new file mode 100644
index 0000000..e58cfb9
--- /dev/null
+++ b/.idea/runConfigurations/picoc_complete_c.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/runConfigurations/picoc_expressions_c.xml b/.idea/runConfigurations/picoc_expressions_c.xml
new file mode 100644
index 0000000..0f28a15
--- /dev/null
+++ b/.idea/runConfigurations/picoc_expressions_c.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/runConfigurations/picoc_factorial_c.xml b/.idea/runConfigurations/picoc_factorial_c.xml
new file mode 100644
index 0000000..4d57993
--- /dev/null
+++ b/.idea/runConfigurations/picoc_factorial_c.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/runConfigurations/picoc_loop_c.xml b/.idea/runConfigurations/picoc_loop_c.xml
new file mode 100644
index 0000000..f81ef53
--- /dev/null
+++ b/.idea/runConfigurations/picoc_loop_c.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/runConfigurations/picoc_md5_c.xml b/.idea/runConfigurations/picoc_md5_c.xml
new file mode 100644
index 0000000..ed77b0c
--- /dev/null
+++ b/.idea/runConfigurations/picoc_md5_c.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/c-tests/.gitignore b/c-tests/.gitignore
new file mode 100644
index 0000000..59be43b
--- /dev/null
+++ b/c-tests/.gitignore
@@ -0,0 +1,2 @@
+*
+!*.*
diff --git a/c-tests/basic.c b/c-tests/basic.c
new file mode 100644
index 0000000..1682198
--- /dev/null
+++ b/c-tests/basic.c
@@ -0,0 +1,7 @@
+int a, b;
+
+int main(void) {
+ a = 1 + 2;
+ b = a + 3;
+ return 0;
+}
diff --git a/c-tests/complete.c b/c-tests/complete.c
new file mode 100644
index 0000000..779a9b3
--- /dev/null
+++ b/c-tests/complete.c
@@ -0,0 +1,73 @@
+typedef int int_type;
+
+struct a_struct {
+ int a;
+ int b;
+};
+
+union a_union {
+ int a;
+ int b;
+};
+
+#pragma a_pragma
+
+int a;
+unsigned long b = 0;
+int *c;
+char arr[5] = "test";
+
+int dbl(int a, ...) {
+ return a * 2;
+}
+
+int main(void) {
+ a = 1 + 2;
+ b = dbl(a);
+
+ if (a < 1) {
+ return 1;
+ }
+
+ while (0) {
+ a++;
+ continue;
+ }
+
+ do {
+ a--;
+ } while (0);
+
+ for (int i = 0; i < 10; i++) {
+ a += 2;
+ }
+
+ lab: a = 1;
+ goto lab;
+
+ struct a_struct s;
+ struct a_struct *sp = &s;
+ s.a = 1;
+ sp->b = 2;
+
+ switch (a) {
+ case 1:
+ b = 1;
+ break;
+ case 2:
+ b = 2;
+ break;
+ default:
+ b = 0;
+ }
+
+ a = b ? 1 : 2;
+
+ a += (int)10;
+
+ for(;;);
+
+ int c = a, b;
+
+ return 0, 1;
+}
diff --git a/c-tests/expressions.c b/c-tests/expressions.c
new file mode 100644
index 0000000..4cfa69d
--- /dev/null
+++ b/c-tests/expressions.c
@@ -0,0 +1,18 @@
+int b, c;
+int d[2];
+
+int main(int argc, char **argv)
+{
+ int a = 1 + 2;
+ b = a + 3 + 4 + 5;
+ c = (a * b++ + 6 - 7) / 8;
+ a += 1;
+ b++;
+ a = b + c;
+ d[0] = 1;
+// *(d + 1) = 2;
+// return a = 1, b = 2;
+ return a = 1;
+
+ a = b++;
+}
diff --git a/c-tests/factorial.c b/c-tests/factorial.c
new file mode 100644
index 0000000..f58e8a1
--- /dev/null
+++ b/c-tests/factorial.c
@@ -0,0 +1,17 @@
+#include
+#include
+
+
+int main(int argc, char **argv)
+{
+ int in = atoi(argv[1]);
+ int fact = 1;
+
+ for (int i = 1; i <= in; i++) {
+ fact *= i;
+ }
+
+ printf("%d factorial is %d", in, fact);
+
+ return 0;
+}
diff --git a/c-tests/hash.c b/c-tests/hash.c
new file mode 100644
index 0000000..49de179
--- /dev/null
+++ b/c-tests/hash.c
@@ -0,0 +1,202 @@
+/*
+** C implementation of a hash table ADT
+*/
+
+//typedef enum tagReturnCode {SUCCESS, FAIL} ReturnCode;
+#define SUCCESS 0
+#define FAIL 1
+
+
+typedef struct tagEntry
+{
+ char* key;
+ char* value;
+} Entry;
+
+
+
+typedef struct tagNode
+{
+ Entry* entry;
+
+ struct tagNode* next;
+} Node;
+
+
+typedef struct tagHash
+{
+ unsigned int table_size;
+
+ Node** heads;
+
+} Hash;
+
+
+static unsigned int hash_func(char* str, unsigned int table_size)
+{
+ unsigned int hash_value;
+ unsigned int a = 127;
+
+ for (hash_value = 0; *str != 0; ++str)
+ hash_value = (a*hash_value + *str) % table_size;
+
+ return hash_value;
+}
+
+
+int HashCreate(Hash** hash, unsigned int table_size)
+{
+ unsigned int i;
+
+ if (table_size < 1)
+ return FAIL;
+
+ /*
+ * Allocate space for the Hash
+ */
+ if (((*hash) = malloc(sizeof(**hash))) == NULL)
+ return FAIL;
+
+ /*
+ * Allocate space for the array of list heads
+ */
+ if (((*hash)->heads = malloc(table_size*sizeof(*((*hash)->heads)))) == NULL)
+ return FAIL;
+
+ /*
+ * Initialize Hash info
+ */
+ for (i = 0; i < table_size; ++i)
+ {
+ (*hash)->heads[i] = NULL;
+ }
+
+ (*hash)->table_size = table_size;
+
+ return SUCCESS;
+}
+
+
+int HashInsert(Hash* hash, Entry* entry)
+{
+ unsigned int index = hash_func(entry->key, hash->table_size);
+ Node* temp = hash->heads[index];
+
+ HashRemove(hash, entry->key);
+
+ if ((hash->heads[index] = malloc(sizeof(Node))) == NULL)
+ return FAIL;
+
+ hash->heads[index]->entry = malloc(sizeof(Entry));
+ hash->heads[index]->entry->key = malloc(strlen(entry->key)+1);
+ hash->heads[index]->entry->value = malloc(strlen(entry->value)+1);
+ strcpy(hash->heads[index]->entry->key, entry->key);
+ strcpy(hash->heads[index]->entry->value, entry->value);
+
+ hash->heads[index]->next = temp;
+
+ return SUCCESS;
+}
+
+
+
+Entry* HashFind(Hash* hash, char* key)
+{
+ unsigned int index = hash_func(key, hash->table_size);
+ Node* temp = hash->heads[index];
+
+ while (temp != NULL)
+ {
+ if (!strcmp(key, temp->entry->key))
+ return temp->entry;
+
+ temp = temp->next;
+ }
+
+ return NULL;
+}
+
+
+int HashRemove(Hash* hash, char* key)
+{
+ unsigned int index = hash_func(key, hash->table_size);
+ Node* temp1 = hash->heads[index];
+ Node* temp2 = temp1;
+
+ while (temp1 != NULL)
+ {
+ if (!strcmp(key, temp1->entry->key))
+ {
+ if (temp1 == hash->heads[index])
+ hash->heads[index] = hash->heads[index]->next;
+ else
+ temp2->next = temp1->next;
+
+ free(temp1->entry->key);
+ free(temp1->entry->value);
+ free(temp1->entry);
+ free(temp1);
+ temp1 = NULL;
+
+ return SUCCESS;
+ }
+
+ temp2 = temp1;
+ temp1 = temp1->next;
+ }
+
+ return FAIL;
+}
+
+
+void HashPrint(Hash* hash, void (*PrintFunc)(char*, char*))
+{
+ unsigned int i;
+
+ if (hash == NULL || hash->heads == NULL)
+ return;
+
+ for (i = 0; i < hash->table_size; ++i)
+ {
+ Node* temp = hash->heads[i];
+
+ while (temp != NULL)
+ {
+ PrintFunc(temp->entry->key, temp->entry->value);
+ temp = temp->next;
+ }
+ }
+}
+
+
+
+void HashDestroy(Hash* hash)
+{
+ unsigned int i;
+
+ if (hash == NULL)
+ return;
+
+ for (i = 0; i < hash->table_size; ++i)
+ {
+ Node* temp = hash->heads[i];
+
+ while (temp != NULL)
+ {
+ Node* temp2 = temp;
+
+ free(temp->entry->key);
+ free(temp->entry->value);
+ free(temp->entry);
+
+ temp = temp->next;
+
+ free(temp2);
+ }
+ }
+
+ free(hash->heads);
+ hash->heads = NULL;
+
+ free(hash);
+}
diff --git a/c-tests/loop.c b/c-tests/loop.c
new file mode 100644
index 0000000..5c1c46c
--- /dev/null
+++ b/c-tests/loop.c
@@ -0,0 +1,10 @@
+int main(int argc, char **argv)
+{
+ int j = 0;
+
+ for (int i = 0; i < 4; i++) {
+ j = i + 2;
+ }
+
+ return 0;
+}
diff --git a/c-tests/md5.c b/c-tests/md5.c
new file mode 100644
index 0000000..a0746f0
--- /dev/null
+++ b/c-tests/md5.c
@@ -0,0 +1,175 @@
+/*
+ * Simple MD5 implementation
+ *
+ * Compile with: gcc -o md5 md5.c
+ */
+#include
+#include
+#include
+// #include
+
+// Mostly ok, but not as a function return type for some reason
+typedef unsigned char uint8_t;
+typedef unsigned int uint32_t;
+typedef unsigned int size_t;
+
+// Constants are the integer part of the sines of integers (in radians) * 2^32.
+uint32_t k[64] = {
+0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee ,
+0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501 ,
+0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be ,
+0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821 ,
+0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa ,
+0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8 ,
+0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed ,
+0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a ,
+0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c ,
+0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70 ,
+0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05 ,
+0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665 ,
+0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039 ,
+0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1 ,
+0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1 ,
+0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391 };
+
+// r specifies the per-round shift amounts
+uint32_t r[] = {7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22,
+ 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20,
+ 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23,
+ 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21};
+
+unsigned int left_rotate(uint32_t x, uint32_t c) {
+ return (x << c) | (x >> (32 - c));
+}
+
+void to_bytes(uint32_t val, uint8_t *bytes)
+{
+ bytes[0] = (uint8_t) val;
+ bytes[1] = (uint8_t) (val >> 8);
+ bytes[2] = (uint8_t) (val >> 16);
+ bytes[3] = (uint8_t) (val >> 24);
+}
+
+unsigned int to_int32(uint8_t *bytes)
+{
+ return (uint32_t) bytes[0]
+ | ((uint32_t) bytes[1] << 8)
+ | ((uint32_t) bytes[2] << 16)
+ | ((uint32_t) bytes[3] << 24);
+}
+
+void md5(uint8_t *initial_msg, size_t initial_len, uint8_t *digest) {
+
+ // These vars will contain the hash
+ uint32_t h0, h1, h2, h3;
+
+ // Message (to prepare)
+ uint8_t *msg = NULL;
+
+ size_t new_len, offset;
+ uint32_t w[16];
+ uint32_t a, b, c, d, i, f, g, temp;
+
+ // Initialize variables - simple count in nibbles:
+ h0 = 0x67452301;
+ h1 = 0xefcdab89;
+ h2 = 0x98badcfe;
+ h3 = 0x10325476;
+
+ //Pre-processing:
+ //append "1" bit to message
+ //append "0" bits until message length in bits ≡ 448 (mod 512)
+ //append length mod (2^64) to message
+
+ for (new_len = initial_len + 1; new_len % (512/8) != 448/8; new_len++);
+
+ msg = malloc(new_len + 8);
+ memcpy(msg, initial_msg, initial_len);
+ msg[initial_len] = 0x80; // append the "1" bit; most significant bit is "first"
+ for (offset = initial_len + 1; offset < new_len; offset++)
+ msg[offset] = 0; // append "0" bits
+
+ // append the len in bits at the end of the buffer.
+ to_bytes(initial_len*8, msg + new_len);
+ // initial_len>>29 == initial_len*8>>32, but avoids overflow.
+ to_bytes(initial_len>>29, msg + new_len + 4);
+
+ // Process the message in successive 512-bit chunks:
+ //for each 512-bit chunk of message:
+ for(offset=0; offset