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..c517e2c4270cebf234a7bb06fa0db7310ce092e9 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,319 @@ 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:
+        o << setw(8) << "aassign "
+          << setw(8) << sym1
+          << setw(8) << int1
+          << setw(8) << sym3;
+        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..74a32334f99489e62016f23eb6eed2ce23a60fd9 100644
--- a/lab3-4/symtab.cc
+++ b/lab3-4/symtab.cc
@@ -7,7 +7,8 @@ using namespace std;
 
 /*
  * Global variables
- */
+*/
+
 
 FunctionInformation *currentFunction;
 TypeInformation     *kIntegerType;
@@ -42,6 +43,9 @@ ostream& SymbolInformation::print(ostream& o)
     case kShortFormat:
         o << id;
         break;
+    case kCFormat:
+        o << id;
+        break;		
     default:
         o << "Bad output format\n";
         abort();
@@ -55,7 +59,7 @@ ostream& TypeInformation::print(ostream& o)
     switch (outputFormat)
     {
     case kFullFormat:
-        o << "TypeInformation @ " << (void*)this << '\n';
+        o << "/*TypeInformation @ " << (void*)this << '\n';
         o << "  Tag:   " << tag << '\n';
         o << "  ID:    " << id << '\n';
         o << "  Table: " << (void*)table << '\n';
@@ -64,7 +68,8 @@ ostream& TypeInformation::print(ostream& o)
         o << '\n';
         o << "  Dimensions:  " << arrayDimensions << '\n';
         o << "  Size:  " << size << '\n';
-
+	o << "*/";
+	break;
     case kSummaryFormat:
         o << (void*)this << ' ';
         if (elementType != NULL)
@@ -79,7 +84,7 @@ ostream& TypeInformation::print(ostream& o)
             o << id;
         }
         
-        o << " [" << size << "]";
+        o << " [" << size << "] ";
         break;
         
     case kShortFormat:
@@ -94,7 +99,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";
@@ -117,7 +131,7 @@ ostream& VariableInformation::print(ostream& o)
         o << '\n';
         o << "  Next:  " << (void*)prev << ' ';
         if (prev) o << SummarySymbols << prev << LongSymbols;
-        o << '\n';
+        o << "\n";
         break;
 
     case kSummaryFormat:
@@ -133,6 +147,10 @@ ostream& VariableInformation::print(ostream& o)
         o << id;
         break;
 
+    case kCFormat:
+      o << id;
+      break;
+
     default:
         o << "Bad output format\n";
         abort();
@@ -148,7 +166,7 @@ ostream& FunctionInformation::print(ostream& o)
     switch (outputFormat)
     {
     case kFullFormat:
-        o << "FunctionInformation @ " << (void*)this << '\n';
+        o << "  FunctionInformation @ " << (void*)this << '\n';
         o << "  Tag:     " << tag << '\n';
         o << "  ID:      " << id << '\n';
         o << "  Table:   " << (void*)table << '\n';
@@ -169,6 +187,7 @@ ostream& FunctionInformation::print(ostream& o)
                 tmp = tmp->prev;
             }
             o << LongSymbols;
+	    o << "/*";
         }
         else
         {
@@ -185,21 +204,22 @@ ostream& FunctionInformation::print(ostream& o)
                 tmp = tmp->prev;
             }
             o << LongSymbols;
+	    o << "\n";
         }
         else
         {
             o << "  Locals: none\n";
         }
         
-        o << "  Body:  " << (void*)body << '\n';
+        o << "Body:  " << (void*)body << '\n';
         if (body) o << body;
-        o << '\n';
+        o << "*/\n";
 
         o << "  Quads: " << (void*)quads << '\n';
         if (quads) o << quads;
-        o << '\n';
+        o << "\n";
         
-        o << symbolTable;
+        o << "\n" << symbolTable << "\n";
         break;
 
     case kSummaryFormat:
@@ -222,6 +242,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 +456,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 +628,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..351633057d5ad11d4e3049282516af77f42418ce
--- /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..3229089388a78314fd61fd338881cd26a07e6445
--- /dev/null
+++ b/lab3-4/test/factorial_test.prog
@@ -0,0 +1,24 @@
+/*
+  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..a6ebcc1a8261fee64e38e38267d29dee88d20cd2
--- /dev/null
+++ b/lab3-4/test/fibonacci_test.prog
@@ -0,0 +1,30 @@
+/*
+  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..734c57d18cd35bab611e51f07f3aa41bb27b5d9e
--- /dev/null
+++ b/lab3-4/test/simple_array_test.prog
@@ -0,0 +1,27 @@
+/*
+ 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..77b92d5111b8d8142c72f6374fefd3f665060f0e
--- /dev/null
+++ b/lab3-4/test/sort_test.prog
@@ -0,0 +1,63 @@
+/*
+  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