diff --git a/lab3-4/Makefile b/lab3-4/Makefile
index f5294b149b5dc292c8d8dc147cabf45ab5b550fd..a8e7fee206b62ace085a68116e30684de422b136 100644
--- a/lab3-4/Makefile
+++ b/lab3-4/Makefile
@@ -15,6 +15,8 @@ OUTFILE =	compiler
 
 FLEX	= flex
 BISON	= bison
+TESTFILES=expression_test.c factorial_test.c fibonacci_test.c sort_test.c simple_array_test.c
+TESTEXECS=expression_test factorial_test fibonacci_test sort_test simple_array_test
 
 DPFILE  =	Makefile.dependencies
 
@@ -39,10 +41,9 @@ parser.o : parser.cc
 	$(CC) $(CFLAGS) -c $<
 
 clean : 
-	rm -f $(OBJECTS) core *~ scanner.cc parser.cc parser.hh $(DPFILE) $(OUTFILE) parser.cc.output
+	rm -f $(OBJECTS) core *~ scanner.cc parser.cc parser.hh $(DPFILE) $(OUTFILE) parser.cc.output  $(TESTFILES) $(TESTEXECS)
 	touch $(DPFILE)
 
-
 $(DPFILE) depend : $(BASESRC) $(HEADERS)
 	$(CC) $(DPFLAGS) $(CFLAGS) $(BASESRC) > $(DPFILE)
 
diff --git a/lab3-4/codegen-test.sh b/lab3-4/codegen-test.sh
new file mode 100644
index 0000000000000000000000000000000000000000..4c4aa3aa0236dc9dc6cbd67fc113cd876cf8c10c
--- /dev/null
+++ b/lab3-4/codegen-test.sh
@@ -0,0 +1,258 @@
+#!bin/bash
+# Author: John Tinnerholm(johti17) johti17@liu.se
+# This file tests if the last lab (Lab-4 generates correct code)
+# Simple passing this test might not be enough to complete the laboration since there might be other issues..
+# To the curious reader, yes this could have been solved by a function..
+
+echo "****Testing Lab 4****"
+echo "Testing simple expressions"
+./compiler -c ./test/expression_test.prog > expression_test.c
+if [ $? -eq 0 ]; then
+    echo "Compilation-OK"
+else
+    echo "Compilation-Failed.. exiting"
+    exit 1
+fi
+
+echo "Frontend OK"
+echo "Translating to C-Code..."
+
+gcc expression_test.c -o  expression_test -lm
+
+if [ $? -eq 0 ]; then
+    echo "C-Code-Compilation-OK"
+else
+    echo "C-Code-Compilation-Failed.. exiting"
+    exit 1
+fi
+
+echo "Testing the expression_test"
+
+
+./expression_test > expression_output
+
+if [ $? -eq 0 ]; then
+    echo "Program ran sucessfully"
+else
+    echo "Program-Failed.. exiting"
+    exit 1
+fi
+
+echo "Checking that we get the correct output.."
+
+if cmp -s "./expression_output" "test/expression_output_ref"; then
+    echo "The program generated the correct output"
+else
+    echo "The output does not match..."
+    diff -y expression_output ./test/expression_output_ref
+    echo "Exiting.."
+    exit 1
+fi
+echo "Removing the testfile: rm expression_output"
+#Remove the testfile
+rm expression_output
+echo "***********************"
+echo "expression_test passed!"
+echo "***********************"
+#= Factorial =#
+echo "Testing factorial_test"
+./compiler -c ./test/factorial_test.prog > factorial_test.c
+if [ $? -eq 0 ]; then
+    echo "Compilation-OK"
+else
+    echo "Compilation-Failed.. exiting"
+    exit 1
+fi
+
+echo "Frontend OK"
+echo "Translating to C-Code..."
+
+gcc factorial_test.c -o  factorial_test -lm
+
+if [ $? -eq 0 ]; then
+    echo "C-Code-Compilation-OK"
+else
+    echo "C-Code-Compilation-Failed.. exiting"
+    exit 1
+fi
+
+echo "Testing the factorial_test"
+
+
+./factorial_test > factorial_output
+
+if [ $? -eq 0 ]; then
+    echo "Program ran sucessfully"
+else
+    echo "Program-Failed.. exiting"
+    exit 1
+fi
+
+echo "Checking that we get the correct output.."
+
+if cmp -s "./factorial_output" "test/factorial_output_ref"; then
+    echo "The program generated the correct output"
+else
+    echo "The output does not match..."
+    diff -y factorial_output ./test/factorial_output_ref
+    echo "Exiting.."
+    exit 1
+fi
+echo "Removing the testfile: rm factorial_output"
+#Remove the testfile
+rm factorial_output
+echo "***********************"
+echo "factorial_test passed!"
+echo "***********************"
+#= Fibonacci =#
+echo "Testing fibonacci_test"
+./compiler -c ./test/fibonacci_test.prog > fibonacci_test.c
+if [ $? -eq 0 ]; then
+    echo "Compilation-OK"
+else
+    echo "Compilation-Failed.. exiting"
+    exit 1
+fi
+
+echo "Frontend OK"
+echo "Translating to C-Code..."
+
+gcc fibonacci_test.c -o  fibonacci_test -lm
+
+if [ $? -eq 0 ]; then
+    echo "C-Code-Compilation-OK"
+else
+    echo "C-Code-Compilation-Failed.. exiting"
+    exit 1
+fi
+
+echo "Testing the fibonacci_test"
+
+
+./fibonacci_test > fibonacci_output
+
+if [ $? -eq 0 ]; then
+    echo "Program ran sucessfully"
+else
+    echo "Program-Failed.. exiting"
+    exit 1
+fi
+
+echo "Checking that we get the correct output.."
+
+if cmp -s "./fibonacci_output" "test/fibonacci_output_ref"; then
+    echo "The program generated the correct output"
+else
+    echo "The output does not match..."
+    diff -y fibonacci_output ./test/fibonacci_output_ref
+    echo "Exiting.."
+    exit 1
+fi
+echo "Removing the testfile: rm fibonacci_output"
+#Remove the testfile
+rm fibonacci_output
+echo "***********************"
+echo "fibonacci_test passed!"
+echo "***********************"
+#= Simple array =#
+echo "Testing simple_array_test"
+./compiler -c ./test/simple_array_test.prog > simple_array_test.c
+if [ $? -eq 0 ]; then
+    echo "Compilation-OK"
+else
+    echo "Compilation-Failed.. exiting"
+    exit 1
+fi
+
+echo "Frontend OK"
+echo "Translating to C-Code..."
+
+gcc simple_array_test.c -o  simple_array_test -lm
+
+if [ $? -eq 0 ]; then
+    echo "C-Code-Compilation-OK"
+else
+    echo "C-Code-Compilation-Failed.. exiting"
+    exit 1
+fi
+
+echo "Testing the simple_array_test"
+
+
+./simple_array_test > simple_array_test_output
+
+if [ $? -eq 0 ]; then
+    echo "Program ran sucessfully"
+else
+    echo "Program-Failed.. exiting"
+    exit 1
+fi
+
+echo "Checking that we get the correct output.."
+
+if cmp -s "./simple_array_test_output" "test/simple_array_test_output_ref"; then
+    echo "The program generated the correct output"
+else
+    echo "The output does not match..."
+    diff -y simple_array_test_output ./test/simple_array_test_output_ref
+    echo "Exiting.."
+    exit 1
+fi
+echo "Removing the testfile: rm simple_array_output"
+#Remove the testfile
+rm simple_array_test_output
+echo "***********************"
+echo "simple_array_test passed!"
+echo "***********************"
+
+
+#= Simple array =#
+echo "Testing sort_test"
+./compiler -c ./test/sort_test.prog > sort_test.c
+if [ $? -eq 0 ]; then
+    echo "Compilation-OK"
+else
+    echo "Compilation-Failed.. exiting"
+    exit 1
+fi
+
+echo "Frontend OK"
+echo "Translating to C-Code..."
+
+gcc sort_test.c -o  sort_test -lm
+
+if [ $? -eq 0 ]; then
+    echo "C-Code-Compilation-OK"
+else
+    echo "C-Code-Compilation-Failed.. exiting"
+    exit 1
+fi
+
+echo "Testing the sort_test"
+
+
+./sort_test > sort_test_output
+
+if [ $? -eq 0 ]; then
+    echo "Program ran sucessfully"
+else
+    echo "Program-Failed.. exiting"
+    exit 1
+fi
+
+echo "Checking that we get the correct output.."
+
+if cmp -s "./sort_test_output" "test/sort_test_output_ref"; then
+    echo "The program generated the correct output"
+else
+    echo "The output does not match..."
+    diff -y sort_test_output ./test/sort_test_output_ref
+    echo "Exiting.."
+    exit 1
+fi
+echo "Removing the testfile: rm simple_array_output"
+#Remove the testfile
+rm sort_test_output
+echo "***********************"
+echo "sort_test passed!"
+echo "***********************"
diff --git a/lab3-4/codegen.cc b/lab3-4/codegen.cc
index 3212f7930d9ca0a8978fd0f662c2401c81b46e97..a49b68265f38f3674f39b3b18251ffd777455ef8 100644
--- a/lab3-4/codegen.cc
+++ b/lab3-4/codegen.cc
@@ -593,10 +593,11 @@ VariableInformation *NotEqual::GenerateCode(QuadsList& q)
     VariableInformation *r0;
 
     r0 = BinaryGenerateCode(q, req, ieq, left, right, this, kIntegerType);
+    auto result = currentFunction->TemporaryVariable(kIntegerType);
     q += new Quad(inot,
 		  dynamic_cast<SymbolInformation*>(r0),
 		  static_cast<SymbolInformation*>(NULL),
-		  dynamic_cast<SymbolInformation*>(r0));
+		  dynamic_cast<SymbolInformation*>(result));
     return r0;
 }
 
@@ -965,6 +966,323 @@ ostream& Quad::print(ostream& o)
 }
 
 
+
+void QuadsList::print_c(ostream& o)
+{
+    QuadsListElement        *elem;
+
+    elem = head;
+    o << ShortSymbols;
+    while (elem)
+    {
+      //        o << elem->data << '\n';
+	elem->data->print_c(o);
+	o << "\n";
+        elem = elem->next;
+    }
+
+    o << CFormat;
+}
+
+void Quad::print_c(ostream& o)
+{
+    o << "    ";
+    static ::string ss = "(";
+    static bool firstParam = true;
+    switch(opcode)
+    {
+    case iconst:
+        o << setw(8) << "integer"
+          << setw(8) << sym3
+          << setw(8) << "="
+          << setw(8) << int1;
+        break;
+    case rconst:
+        o << setw(8) <<"real"
+          << setw(8) << sym3
+	  << setw(8) << "="
+          << setw(8) << real1;
+        break;
+    case iaddr:
+      o	  << setw(8) << "integer"
+	  << setw(8) << sym3
+	  << setw(8) << "="
+          << setw(8) << "(integer)" << sym1;
+        break;
+    case itor:
+        o << setw(8) <<  "real"
+	  << setw(8) << sym3
+	  << setw(8) <<"="
+          << setw(8) << "(real)"<< sym1;
+        break;
+    case rtrunc:
+        o << setw(8) << "integer"
+	  << setw(8) << sym3
+          << setw(8) <<"="
+          << setw(8) << "(integer)" <<sym3;
+        break;
+    case iadd:
+      o << setw(8) << "integer"
+	<< setw(8) << sym3
+	  << setw(8) << " = "
+          << setw(8) << sym1
+	  << setw(8) << " + "
+          << setw(8) << sym2;
+        break;
+    case isub:
+      o << setw(8) << "integer"
+	  << setw(8) << sym3
+	  << setw(8) << " = "
+          << setw(8) << sym1
+	  << setw(8) << " - "
+          << setw(8) << sym2;
+        break;
+    case imul:
+        o << setw(8) << "integer"
+          << setw(8) << sym3
+	  << setw(8) << " = "
+          << setw(8) << sym1
+	  << setw(8) << " * "
+          << setw(8) << sym2;
+        break;
+    case idiv:
+        o << setw(8) << "real"
+	  << setw(8) << sym3
+	  << setw(8) << "="
+          << setw(8) << sym1
+	  << setw(8) << "/"
+          << setw(8) << sym2;
+        break;
+    case ipow:
+      o   << setw(8) << "real"
+	  << setw(8) << sym3
+	  << setw(8) << "= pow("
+          << setw(8) << sym1
+	  << setw(8) << ","
+          << setw(8) << sym2 << ")";
+        break;
+    case radd:
+      o   << setw(8) << "real"
+	  << setw(8) << sym3
+          << setw(8) << "="
+          << setw(8) << sym1
+	  << setw(8) << "+"
+          << setw(8) << sym2;
+        break;
+    case rsub:
+       o  << setw(8)  << "real"
+	  << setw(8) << sym3
+          << setw(8) << "="
+          << setw(8) << sym1
+	  << setw(8) << "-"
+          << setw(8) << sym2;
+        break;
+    case rmul:
+      o  << setw(8)  << "real"
+	  << setw(8) << sym3
+          << setw(8) << "="
+          << setw(8) << sym1
+	  << setw(8) << "*"
+          << setw(8) << sym2;
+        break;
+    case rdiv:
+        o  << setw(8) << "real"
+	  << setw(8) << sym3
+          << setw(8) << "="
+          << setw(8) << sym1
+	  << setw(8) << "/"
+          << setw(8) << sym2;
+        break;
+    case rpow:
+      o   << setw(8) << "real "
+	  << setw(8) << sym3
+	  << setw(8) << "= pow("
+          << setw(8) << sym1
+	  << setw(8) << ","
+          << setw(8) << sym2 << ")";
+        break;
+    case igt:
+        o << setw(8) << "conditional"
+	  << setw(8) << sym3
+          << setw(8) << "="
+          << setw(8) << sym1
+	  << setw(8) << ">"
+          << setw(8) << sym2;
+        break;
+    case ilt:
+      o << setw(8) << "conditional"
+	  << setw(8) << sym3
+          << setw(8) << "="
+          << setw(8) << sym1
+	  << setw(8) << "<"
+          << setw(8) << sym2;
+        break;
+    case ieq:
+          o << setw(8) << "conditional"
+	    << setw(8) << sym3
+	    << setw(8) << "="
+	    << setw(8) << sym1
+	    << setw(8) << "=="
+	    << setw(8) << sym2;
+        break;
+    case rgt:
+     o << setw(8) << "conditional"
+	  << setw(8) << sym3
+          << setw(8) << "="
+          << setw(8) << sym1
+	  << setw(8) << ">"
+          << setw(8) << sym2;
+        break;
+    case rlt:
+     o << setw(8) << "conditional"
+	  << setw(8) << sym3
+          << setw(8) << "="
+          << setw(8) << sym1
+	  << setw(8) << "<"
+          << setw(8) << sym2;
+        break;
+    case req:
+     o << setw(8) << "conditional"
+	  << setw(8) << sym3
+          << setw(8) << "="
+          << setw(8) << sym1
+	  << setw(8) << "=="
+          << setw(8) << sym2;
+     break;
+    case iand:
+        o << setw(8) << "conditional"
+	  << setw(8) << sym3
+          << setw(8) << "="
+          << setw(8) << sym1
+	  << setw(8) << "&&"
+          << setw(8) << sym2;
+	break;
+    case ior:
+      o << setw(8) << "conditional"
+	  << setw(8) << sym3
+          << setw(8) << "="
+          << setw(8) << sym1
+	  << setw(8) << "||"
+          << setw(8) << sym2;
+        break;
+    case inot:
+        o << setw(8) << "conditional"
+          << setw(8) << sym3
+          << setw(8) << "="
+	  << setw(8) << "!"
+          << setw(8) << sym3;
+        break;
+    case jtrue:
+      o << setw(8) << "if("
+	<< setw(8) << sym2
+	<< setw(8) << ")"
+	<< setw(8)
+	<< setw(8) << "goto clabel" << int1;
+        break;
+    case jfalse:
+      o << setw(8) << "if(!"
+	<< setw(8) << sym2 << setw(8) << ")"
+	<< setw(8)
+	<< setw(8) << "goto clabel" << int1;
+        break;
+    case jump:
+        o << setw(8) << "goto    "
+          << setw(8) << "clabel"
+	  << int1
+          << setw(8) << "/*jmp*/";
+        break;
+    case clabel:
+        o << setw(8) << "clabel"
+          << int1
+          << ":";
+        break;
+    case istore:
+         o << setw(8) << ""
+	  << setw(8) << "*(integer*)" << sym3
+          << setw(8) << "="
+          << setw(8) << sym1;
+        break;
+        break;
+    case iload:
+    	 o << setw(8) << "integer"
+          << setw(8) << sym3
+          << setw(8) << "= /*iload*/"
+          << setw(8) << "*(integer*)" << sym1;
+        break;
+    case rstore:
+        o << setw(8) << ""
+	  << setw(8) << "*(real*)" << sym3
+          << setw(8) << "="
+          << setw(8) << sym1;
+        break;
+    case rload:
+        o
+	  << setw(8) << "real"
+          << setw(8) << sym3
+          << setw(8) << "= /*rload*/"
+          << setw(8) << "*(real*)" << sym1;
+        break;
+    case creturn:
+        o << setw(8) << "return "
+          << setw(8) << sym3
+          << setw(8)
+	  << setw(8) << "/*Return statement*/";
+        break;
+    case param: {
+      if (firstParam) {
+	ss = ss + sym1->id;
+	firstParam = false;
+      } else {
+	ss = ss + "," + sym1->id;
+      }
+    }
+      break;
+    case call: {
+      o << setw(8) << "integer " << sym3 //Let it be ints for now..
+	<< setw(8) << "="
+        << setw(8) << sym1
+	<< setw(8) << ss
+	<< setw(8) << ")";
+	ss = "("; //Reset callstack
+	firstParam = true;
+     }
+        break;
+    case iassign:
+        o << setw(8) << sym3
+          << setw(8) << "="
+          << setw(8) << sym1;
+        break;
+    case rassign:
+        o << setw(8) << sym3
+          << setw(8) << "="
+          << setw(8) << sym1;
+        break;
+    case aassign: {
+      ::string itVar = sym1->id + "_" + ::string(int1);
+      o << setw(8) << "for(int " << itVar << " = 0 ;"
+	<< setw(8) << itVar << "<" << int1 << ";"
+	<< setw(8) << itVar << "++;)" //Increment & close for loop.
+	/*Assign the array*/
+	<< setw(8) << sym3 << "[" << itVar << "]" << "="
+	<< setw(8) << sym1 << "[" << itVar << "];";
+    }
+        break;
+    case hcf:
+      o << setw(8) << "exit(-1)";
+        break;
+    case nop:
+      o << setw(8) << ";/*No operation*/"
+	<< setw(8) << "";
+        break;
+    default:
+        o << "unknown (" << opcode << ")";
+        break;
+    }
+    //Add semicolon to all statements
+    o << setw(8) << ";";
+}
+
+
 ostream& operator<<(ostream& o, QuadsList *q)
 {
     if (q != NULL)
diff --git a/lab3-4/codegen.hh b/lab3-4/codegen.hh
index d6eff4c1fdd4b8c6d4a04814f5282344eed47a63..0d9f2848b7f3b734a524e87939838ff0109afbfc 100644
--- a/lab3-4/codegen.hh
+++ b/lab3-4/codegen.hh
@@ -87,9 +87,9 @@ class Quad
 {
 private:
     ostream& print(ostream&);
-
 public:
     tQuadType        opcode;
+    void print_c(ostream& o);
 
     //
     // Arguments. Make sure you initialize the right ones!
@@ -162,8 +162,8 @@ class QuadsList
     static long              labelCounter;
 
     ostream& print(ostream&);
-    
 public:
+    void print_c(ostream&);
     QuadsList() :
         head(NULL),
         tail(NULL) {};
diff --git a/lab3-4/main.cc b/lab3-4/main.cc
index bf0b53055b650ad34cf55e509135836e013cb5c2..651111cefd5cd06aee23e259598525764c8e88bd 100644
--- a/lab3-4/main.cc
+++ b/lab3-4/main.cc
@@ -13,17 +13,18 @@ extern int yydebug;
 extern int errorCount;
 extern int warningCount;
 
-static char *optionString = "dh";
+static char *optionString = "dhc";
 
 void Usage(char *program)
 {
     cerr << "Usage:\n"
-         << program << " [-d] [filename]\n"
+         << program << " [-d|-c] [filename]\n"
          << program << " -h\n"
          << "\n"
          << "Options:\n"
          << "  -h               Shows this message.\n"
-         << "  -d               Turn on parser debugging.\n";
+         << "  -d               Turn on parser debugging.\n"
+         << "  -c               Generates a C-representation of the program\n";
 
     exit(1);
 }
@@ -37,11 +38,12 @@ int main(int argc, char **argv)
     // Set up the symbol table
     //
 
-    currentFunction = new FunctionInformation("main.");
+    currentFunction = new FunctionInformation("main");
     kIntegerType    = new TypeInformation("integer", sizeof(long));
     kRealType       = new TypeInformation("real", sizeof(double));
 
     kFPrintFunction = new FunctionInformation("putreal");
+    FunctionInformation *kPLReadFunction = new FunctionInformation("putline");
     kIPrintFunction = new FunctionInformation("putint");
     kFReadFunction = new FunctionInformation("getreal");
     kIReadFunction = new FunctionInformation("getint");
@@ -52,6 +54,7 @@ int main(int argc, char **argv)
     kFPrintFunction->AddParameter("x", kRealType);
     kIReadFunction->SetReturnType(kIntegerType);
     kFReadFunction->SetReturnType(kRealType);
+    kIReadFunction->SetReturnType(kIntegerType);
     
     currentFunction->AddSymbol(kIntegerType);
     currentFunction->AddSymbol(kRealType);
@@ -59,6 +62,7 @@ int main(int argc, char **argv)
     currentFunction->AddSymbol(kFPrintFunction);
     currentFunction->AddSymbol(kIReadFunction);
     currentFunction->AddSymbol(kFReadFunction);
+    currentFunction->AddSymbol(kPLReadFunction);
 
     //
     // Check command-line arguments
@@ -78,7 +82,13 @@ int main(int argc, char **argv)
             break;
         case '?':
             Usage(argv[0]);
-            break;
+            break;    
+	case 'c':
+	  std::cout << "/*Using standard-library*/\n";
+	  std::cout << "#include \"stl.h\"\n";
+	  SymbolInformation::outputFormat = SymbolInformation::kCFormat;
+	  currentFunction->outputFormat = SymbolInformation::kCFormat;
+	  break;
         }
     }
 
@@ -100,8 +110,7 @@ int main(int argc, char **argv)
     // Compile the input
     //
 
-    yyparse();
-
-    return 0;
+    int retcode = yyparse();
+    return retcode;
 }
     
diff --git a/lab3-4/stl.h b/lab3-4/stl.h
new file mode 100644
index 0000000000000000000000000000000000000000..960f51523906690b8d89bbd17a9cc8846b4b441d
--- /dev/null
+++ b/lab3-4/stl.h
@@ -0,0 +1,49 @@
+/*
+ The quite limited standard library/runtime for your language
+--
+John Tinnerholm
+*/
+
+#include <math.h>
+#include <stdio.h>
+
+//Array preprocessing
+#define array_real(X) real([X])
+#define array_integer(X) real([X])
+
+#define real double
+#define integer long
+#define conditional bool
+#define bool integer
+
+
+integer putint(long x) {
+  printf("%ld", x);
+  return 0;
+}
+
+integer putreal(double x) {
+  printf("%lf", x);
+  return 0;
+}
+
+double getreal() {
+  double r;
+  scanf("%lf", &r);
+  return r;
+}
+
+double getint() {
+  long l;
+  scanf("%ld", &l);
+  return l;
+}
+
+
+integer putline()
+{
+  printf("\n");
+  return 0;
+}
+
+
diff --git a/lab3-4/symtab.cc b/lab3-4/symtab.cc
index e023ac8493f8fe8a66c8b6b4ede4386574552913..337f5fc4124e3b7024351c20c0951b11c843dd1c 100644
--- a/lab3-4/symtab.cc
+++ b/lab3-4/symtab.cc
@@ -42,6 +42,9 @@ ostream& SymbolInformation::print(ostream& o)
     case kShortFormat:
         o << id;
         break;
+    case kCFormat:
+        o << id;
+        break;		
     default:
         o << "Bad output format\n";
         abort();
@@ -64,7 +67,6 @@ ostream& TypeInformation::print(ostream& o)
         o << '\n';
         o << "  Dimensions:  " << arrayDimensions << '\n';
         o << "  Size:  " << size << '\n';
-
     case kSummaryFormat:
         o << (void*)this << ' ';
         if (elementType != NULL)
@@ -94,7 +96,16 @@ ostream& TypeInformation::print(ostream& o)
             o << id;
         }
         break;
-        
+    case kCFormat:
+      if (elementType != NULL)
+        {
+             o << "[" << arrayDimensions << "]";
+        }
+        else
+        {
+	  o << id;
+        }
+        break;
 
     default:
         o << "Bad output format\n";
@@ -133,6 +144,10 @@ ostream& VariableInformation::print(ostream& o)
         o << id;
         break;
 
+    case kCFormat:
+      o << id;
+      break;
+
     default:
         o << "Bad output format\n";
         abort();
@@ -185,6 +200,7 @@ ostream& FunctionInformation::print(ostream& o)
                 tmp = tmp->prev;
             }
             o << LongSymbols;
+	    o << '\n';
         }
         else
         {
@@ -193,8 +209,8 @@ ostream& FunctionInformation::print(ostream& o)
         
         o << "  Body:  " << (void*)body << '\n';
         if (body) o << body;
-        o << '\n';
-
+	o << '\n';
+	
         o << "  Quads: " << (void*)quads << '\n';
         if (quads) o << quads;
         o << '\n';
@@ -222,6 +238,60 @@ ostream& FunctionInformation::print(ostream& o)
     case kShortFormat:
         o << id;
         break;
+
+    case kCFormat:
+      	/*C-Code preamble*/
+	if (returnType == NULL) {
+	  o << "void\n";
+	} else {
+	  o << returnType << "\n";
+	}
+	    
+	o << "" << id << "(";
+	//Parameters
+	if (lastParam != NULL)
+        {
+            tmp = lastParam;
+            while (tmp != NULL)
+            {
+	      if (tmp->type->elementType != NULL){ //Array... 
+		o << tmp->type->elementType << "*" << "\t";
+	      } else {
+		//		o << tmp->type->elementType;
+		o << tmp->type << "\t";
+	      }
+	      if (tmp->prev == NULL) {
+		o << tmp->id;
+	      } else {
+		o << tmp->id << ",";
+	      }
+	      tmp = tmp->prev;
+            }
+        }
+	o << ")\n";
+	/* Generate C-Code for the body! */
+	o << "{\n";
+	if (lastLocal)
+        {
+	  o << "//Locals:\n";
+            tmp = lastLocal;
+            while (tmp != NULL)
+            {
+	      if (tmp->type->elementType != NULL){ //Array...
+		o << tmp->type->elementType;
+		o << "\t";
+		o << tmp;
+		o << tmp->type << ";\n";
+	      }
+	      else {
+		o << tmp->type << "\t" << tmp << ";\n";
+	      }
+	      tmp = tmp->prev;
+            }
+        }
+	quads->print_c(o);
+	o << "}\n";
+	break;
         
     default:
         o << "Bad output format.\n";
@@ -382,7 +452,7 @@ VariableInformation *FunctionInformation::TemporaryVariable(TypeInformation *typ
 
     temporaryCount += 1;
 
-    info = new VariableInformation(::string("T:") + (int)temporaryCount, type);
+    info = new VariableInformation(::string("T_") + (int)temporaryCount, type);
     info->prev = NULL;
     AddSymbol(info);
 
@@ -554,6 +624,12 @@ ostream& LongSymbols(ostream& o)
     return o;
 }
 
+ostream& CFormat(ostream& o)
+{
+    SymbolInformation::outputFormat = SymbolInformation::kCFormat;
+    return o;
+}
+
 ostream& SummarySymbols(ostream& o)
 {
     SymbolInformation::outputFormat = SymbolInformation::kSummaryFormat;
diff --git a/lab3-4/symtab.hh b/lab3-4/symtab.hh
index 9933ed03f02d86c8bad5e9293321b40d8dc9000f..7e06b3ede4fae221a4478d5d26018a81d8106a87 100644
--- a/lab3-4/symtab.hh
+++ b/lab3-4/symtab.hh
@@ -22,6 +22,7 @@ extern FunctionInformation *kFPrintFunction;
 extern FunctionInformation *kIPrintFunction;
 extern FunctionInformation *kFReadFunction;
 extern FunctionInformation *kIReadFunction;
+extern FunctionInformation *kIReadFunction;
 extern TypeInformation *kRealType;
 extern TypeInformation *kIntegerType;
 
@@ -90,13 +91,10 @@ protected:
     friend class SymbolTable;
     friend ostream& LongSymbols(ostream&);
     friend ostream& SummarySymbols(ostream&);
-    friend ostream& ShortSymbols(ostream&);
-
-    typedef enum { kFullFormat, kSummaryFormat, kShortFormat } tFormatType;
-    
-    static tFormatType outputFormat;
-    
+    friend ostream& ShortSymbols(ostream&);        
 public:
+    typedef enum { kFullFormat, kSummaryFormat, kShortFormat, kCFormat } tFormatType;
+    static tFormatType outputFormat;
     SymbolInformationType       tag;
     ::string                      id;
     SymbolTable                *table;
@@ -233,6 +231,7 @@ public:
 
 ostream& ShortSymbols(ostream& o);
 ostream& LongSymbols(ostream& o);
+ostream& CFormat(ostream& o);
 
 
 #endif
diff --git a/lab3-4/test/README.md b/lab3-4/test/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..d294d57c6bbb13201a1c19d26e65f388d43ab26c
--- /dev/null
+++ b/lab3-4/test/README.md
@@ -0,0 +1,33 @@
+# This file contains various files for testing 
+
+## expression_test.prog
+This program simple executes and print simple expressions 
+## factorial_test.prog
+This program checks if functions and if/else statements are handled correctly.
+Checks the factorial function 
+## fibonacci_test.prog 
+Similar to the factorial test, also tests recursions
+## sort_test.prog 
+This program simple executes selection sort on an unsorted array 
+## *output_ref
+These are references files specifing the expected output from the programs above. 
+It is used by codegen-test.sh 
+## How to test? 
+To test a program simply execute codegen-test.sh in the parent directory.
+
+```
+bash codegen-test.sh
+```
+## How do I compile my own program? 
+Invoke the compiler. 
+Pipe the output to a file with the suffix.c 
+```
+compiler -c > <name>.c 
+```
+Do not use the -d flag when doing this. 
+
+Then compile this file with
+```
+gcc -lm <name.c>
+```
+
diff --git a/lab3-4/test/expression_output_ref b/lab3-4/test/expression_output_ref
new file mode 100644
index 0000000000000000000000000000000000000000..06f0020e3ee761427853c94ba35abb6e18a97bea
--- /dev/null
+++ b/lab3-4/test/expression_output_ref
@@ -0,0 +1,10 @@
+3
+0
+4
+1
+4
+3.000000
+0.000000
+4.000000
+1.000000
+4.000000
diff --git a/lab3-4/test/expression_test.prog b/lab3-4/test/expression_test.prog
new file mode 100644
index 0000000000000000000000000000000000000000..f042d94bbe449ab655806245fe759e4e04625bef
--- /dev/null
+++ b/lab3-4/test/expression_test.prog
@@ -0,0 +1,41 @@
+/*
+  This test checks if basic expressions work.
+  Author: John Tinnerholm
+*/
+declare
+    a : integer;
+    b : real;
+begin
+/*Testing integers*/
+ a := 1 + 2;
+ putint(a); //Should be 3
+ putline();
+ a := 2 - 2;
+ putint(a); //Should be 0
+ putline();
+ a := 2 * 2;
+ putint(a); //Should be 4
+ putline();
+ a := 2 / 2;
+ putint(a); //Should be 1
+ putline();
+ a := 2 ^ 2;
+ putint(a); //Should be 4
+ putline();
+/*Testing reals*/
+ b := 1.0 + 2.0;
+ putreal(b); //Should be 3
+ putline();
+ b := 2.0 - 2.0;
+ putreal(b); //Should be 0
+ putline();
+ b := 2.0 * 2.0;
+ putreal(b); //Should be 4
+ putline();
+ b := 2.0 / 2.0;
+ putreal(b); //Should be 1
+ putline();
+ b := 2.0 ^ 2.0;
+ putreal(b); //Should be 4
+ putline();
+end;
diff --git a/lab3-4/test/factorial_output_ref b/lab3-4/test/factorial_output_ref
new file mode 100644
index 0000000000000000000000000000000000000000..97de8a402e55404f9bec1b20743574090c2aa142
--- /dev/null
+++ b/lab3-4/test/factorial_output_ref
@@ -0,0 +1,2 @@
+3
+120
diff --git a/lab3-4/test/factorial_test.prog b/lab3-4/test/factorial_test.prog
new file mode 100644
index 0000000000000000000000000000000000000000..639e15bae1677ef627e36bb90a20fa61d4c4f00f
--- /dev/null
+++ b/lab3-4/test/factorial_test.prog
@@ -0,0 +1,26 @@
+/*
+  This test checks if the factorial function works
+  Author: John Tinnerholm
+*/
+declare
+  a : integer;
+function fac (x : integer) : integer
+begin
+  if x == 0 then
+    begin
+      return 1;
+    end
+    else
+     begin
+       return x * fac(x - 1);
+     end
+  if;
+end;
+
+begin
+  a := 1+2;
+  putint(a); //Should be 3
+  putline();
+  putint(fac(5)); //Should be 120
+  putline();
+end;
diff --git a/lab3-4/test/fibonacci_output_ref b/lab3-4/test/fibonacci_output_ref
new file mode 100644
index 0000000000000000000000000000000000000000..f6cdd598aa3b34353a46a15bf8997de599e13686
--- /dev/null
+++ b/lab3-4/test/fibonacci_output_ref
@@ -0,0 +1,10 @@
+0
+1
+1
+2
+3
+5
+8
+13
+21
+34
diff --git a/lab3-4/test/fibonacci_test.prog b/lab3-4/test/fibonacci_test.prog
new file mode 100644
index 0000000000000000000000000000000000000000..c4c000bb0b50a635d773af1a311200693766b88d
--- /dev/null
+++ b/lab3-4/test/fibonacci_test.prog
@@ -0,0 +1,33 @@
+/*
+  This test checks the fibonacci function
+  Author: John Tinnerholm
+*/
+declare
+    a : integer;
+function fib (x : integer) : integer
+begin
+  if x == 0 then
+    begin
+      return 0;
+    end
+  elseif x == 1 then
+    begin
+      return 1;
+    end
+  else
+    begin
+      return fib(x - 1) + fib(x-2);
+    end
+  if;
+end;
+
+begin
+  a := 0;
+  while a < 10 do
+    begin
+      putint(fib(a));
+      putline();
+      a := a + 1;
+    end
+  while;
+end;
diff --git a/lab3-4/test/simple_array_output_ref b/lab3-4/test/simple_array_output_ref
new file mode 100644
index 0000000000000000000000000000000000000000..283c4a18310f8ea653f2a5fa3c6f2ce3ccbdddfe
--- /dev/null
+++ b/lab3-4/test/simple_array_output_ref
@@ -0,0 +1,5 @@
+1.000000
+2.000000
+3.000000
+4.000000
+5.000000
diff --git a/lab3-4/test/simple_array_test.prog b/lab3-4/test/simple_array_test.prog
new file mode 100644
index 0000000000000000000000000000000000000000..2cd55393ce1267290cc623b9c6456001a10868cf
--- /dev/null
+++ b/lab3-4/test/simple_array_test.prog
@@ -0,0 +1,29 @@
+/*
+ This program initializes an array with 5 elements.
+ it then prints said array.
+ Author: John Tinnerholm
+*/
+declare
+  i : integer;
+  ii : real;
+  elements : array 5 of real;
+begin
+  i := 0;
+  ii := 0.;
+  while i < 5  do
+    begin
+      ii := 1.0 + ii;
+      elements[i] := ii;
+      i := i + 1;
+    end
+  while;
+/* Should print 1,2,3,4,5 */
+  i := 0;
+  while i < 5 do
+    begin
+      putreal(elements[i]);
+      putline();
+      i := i + 1;
+    end
+  while;
+end;
\ No newline at end of file
diff --git a/lab3-4/test/simple_array_test_output_ref b/lab3-4/test/simple_array_test_output_ref
new file mode 100644
index 0000000000000000000000000000000000000000..283c4a18310f8ea653f2a5fa3c6f2ce3ccbdddfe
--- /dev/null
+++ b/lab3-4/test/simple_array_test_output_ref
@@ -0,0 +1,5 @@
+1.000000
+2.000000
+3.000000
+4.000000
+5.000000
diff --git a/lab3-4/test/simple_simple_array.prog b/lab3-4/test/simple_simple_array.prog
new file mode 100644
index 0000000000000000000000000000000000000000..c0de8122caf001febded932fe7d642aedb84e543
--- /dev/null
+++ b/lab3-4/test/simple_simple_array.prog
@@ -0,0 +1,12 @@
+/*
+ We write to the first index of an array.
+ We then print the result
+ Author: John Tinnerholm
+*/
+declare
+    elements : array 1 of real;
+begin
+  elements[0] := 12.;
+  putreal(elements[0]);	
+  putline();
+end;
\ No newline at end of file
diff --git a/lab3-4/test/sort_test.prog b/lab3-4/test/sort_test.prog
new file mode 100644
index 0000000000000000000000000000000000000000..38356d3a33049a4c23f162f87f527e6deae99083
--- /dev/null
+++ b/lab3-4/test/sort_test.prog
@@ -0,0 +1,68 @@
+/*
+  Implementation of selection sort.
+  This checks if nested while loop works among other things..
+  Author: John Tinnerholm
+*/
+declare
+  i : integer;
+  j : integer;
+  tmp1 : integer;
+  current_min : integer;
+  length_of_array : integer;
+  array_to_be_sorted : array 10 of integer;
+begin
+  i := 0;
+  j := 0;
+  length_of_array := 10;
+
+  array_to_be_sorted[0] := 10;
+  array_to_be_sorted[1] := 9;
+  array_to_be_sorted[2] := 8;
+  array_to_be_sorted[3] := 7;
+  array_to_be_sorted[4] := 6;
+  array_to_be_sorted[5] := 5;
+  array_to_be_sorted[6] := 4;
+  array_to_be_sorted[7] := 3;
+  array_to_be_sorted[8] := 2;
+  array_to_be_sorted[9] := 1;
+//Print unsorted array
+  while i < length_of_array do
+    begin
+      putint(array_to_be_sorted[i]);
+      putline();
+      i := i + 1;
+    end
+  while;
+  i := 0;
+  j := 0;
+  while i < length_of_array - 1 do
+    begin
+      current_min := i;
+      j := i + 1;
+      while j < length_of_array do
+        begin
+          if array_to_be_sorted[current_min] > array_to_be_sorted[j] then
+            begin
+              current_min := j;
+            end
+          if;
+          j := j + 1;
+        end
+      while;
+      tmp1 := array_to_be_sorted[i];
+      array_to_be_sorted[i] := array_to_be_sorted[current_min];
+      array_to_be_sorted[current_min] := tmp1;
+      i := i + 1;
+    end
+  while;
+putline();
+/* Print the sorted array*/
+  i := 0;
+  while i < length_of_array do
+    begin
+      putint(array_to_be_sorted[i]);
+      putline();
+      i := i + 1;
+    end
+  while;
+end;
diff --git a/lab3-4/test/sort_test_output_ref b/lab3-4/test/sort_test_output_ref
new file mode 100644
index 0000000000000000000000000000000000000000..5f1f82681404882692d82fe80c3cb68940968f19
--- /dev/null
+++ b/lab3-4/test/sort_test_output_ref
@@ -0,0 +1,21 @@
+10
+9
+8
+7
+6
+5
+4
+3
+2
+1
+
+1
+2
+3
+4
+5
+6
+7
+8
+9
+10
diff --git a/traces/trace-lab3.txt b/traces/trace-lab3.txt
index 1c7a2d1c439f8d556d7956287a5851a56b366ef2..220a27ae9b74b6457ef552e9877ff19f72b86c89 100644
--- a/traces/trace-lab3.txt
+++ b/traces/trace-lab3.txt
@@ -1,18 +1,19 @@
-FunctionInformation @ 0x760330
+FunctionInformation @ 0x7fffd215ded0
   Tag:     0
-  ID:      main.
+  ID:      main
   Table:   0
   Parent:  0 
   Returns: 0 
   Parameters: none
   Locals:
-    0x76a2c0 f
-    0x76a160 e
-    0x76a000 d
-    0x769ea0 c
-    0x769d20 b
-    0x769c88 a
-  Body:  0x76e7a8
+    0x7fffd2170370 f
+    0x7fffd2170110 e
+    0x7fffd216feb0 d
+    0x7fffd216fc50 c
+    0x7fffd216f9d0 b
+    0x7fffd216f8c0 a
+
+  Body:  0x7fffd217b020
 StatementList (statement, preceding)
 +-CallStatement (call)
 | +-FunctionCall (function, arguments) [integer]
@@ -78,25 +79,27 @@ StatementList (statement, preceding)
   Quads: 0
 
 -------------------------------------------------------------------------------
-SymbolTable @ 0x760360
+SymbolTable @ 0x7fffd215df28
 -------------------------------------------------------------------------------
-7	0x76a280 0x76a280 'real<11>.' array 11 of real [88]
-11	0x764510 getint() -> integer
-65	0x769c88 a : 0x761388 integer [4]
-66	0x769d20 b : 0x7613c8 real [8] --> 0x769c88 a
-67	0x769ea0 c : 0x769e60 'integer<10>.' array 10 of integer [40] --> 0x769d20 b
-68	0x76a000 d : 0x769fc0 'integer<11>.' array 11 of integer [44] --> 0x769ea0 c
-69	0x76a160 e : 0x76a120 'real<10>.' array 10 of real [80] --> 0x76a000 d
-70	0x76a2c0 f : 0x76a280 'real<11>.' array 11 of real [88] --> 0x76a160 e
-71	0x76c9f0 g(x) -> array 11 of integer
-88	0x761388 0x761388 integer [4]
-92	0x761408 putreal(x) -> integer
-250	0x76a120 0x76a120 'real<10>.' array 10 of real [80]
-511	0x76b630 fib(x) -> integer
-519	0x76a310 fac(x) -> integer
-603	0x7613c8 0x7613c8 real [8]
-664	0x769fc0 0x769fc0 'integer<11>.' array 11 of integer [44]
-775	0x762460 putint(x) -> integer
-907	0x769e60 0x769e60 'integer<10>.' array 10 of integer [40]
-918	0x7634b8 getreal() -> real
+7	0x7fffd2170300 0x7fffd2170300 'real<11>.' array 11 of real [88]
+11	0x7fffd2168320 getint() -> integer
+65	0x7fffd216f8c0 a : 0x7fffd215ff80 integer [8]
+66	0x7fffd216f9d0 b : 0x7fffd215fff0 real [8] --> 0x7fffd216f8c0 a
+67	0x7fffd216fc50 c : 0x7fffd216fbe0 'integer<10>.' array 10 of integer [80] --> 0x7fffd216f9d0 b
+68	0x7fffd216feb0 d : 0x7fffd216fe40 'integer<11>.' array 11 of integer [88] --> 0x7fffd216fc50 c
+69	0x7fffd2170110 e : 0x7fffd21700a0 'real<10>.' array 10 of real [80] --> 0x7fffd216feb0 d
+70	0x7fffd2170370 f : 0x7fffd2170300 'real<11>.' array 11 of real [88] --> 0x7fffd2170110 e
+70	0x7fffd2170400 f(z; y; x) -> integer
+71	0x7fffd21777b0 g(x) -> array 11 of integer
+88	0x7fffd215ff80 0x7fffd215ff80 integer [8]
+92	0x7fffd2160060 putreal(x) -> integer
+250	0x7fffd21700a0 0x7fffd21700a0 'real<10>.' array 10 of real [80]
+481	0x7fffd2162110 putline() -> no return type
+511	0x7fffd21750c0 fib(x) -> integer
+519	0x7fffd2172b00 fac(x) -> integer
+603	0x7fffd215fff0 0x7fffd215fff0 real [8]
+664	0x7fffd216fe40 0x7fffd216fe40 'integer<11>.' array 11 of integer [88]
+775	0x7fffd21641c0 putint(x) -> integer
+907	0x7fffd216fbe0 0x7fffd216fbe0 'integer<10>.' array 10 of integer [80]
+918	0x7fffd2166270 getreal() -> real
 -------------------------------------------------------------------------------