From 9e6c89f1fa93287104381e02f0bbbdd6060a9382 Mon Sep 17 00:00:00 2001
From: AidenRushbrooke <72034940+AidenRushbrooke@users.noreply.github.com>
Date: Sun, 5 Dec 2021 03:27:18 +0000
Subject: Added subroutines and comments for most files

---
 src/Compiler/Environment.java  |   6 +-
 src/Compiler/ExecuteC.java     |   3 +-
 src/Compiler/Expression.java   |  31 +++++-
 src/Compiler/Language.java     |  60 +++++++---
 src/Compiler/Parser.java       | 241 ++++++++++++++++++++++++++++++++++++++---
 src/Compiler/Statement.java    |  48 +++++++-
 src/Compiler/Token.java        |  18 +--
 src/Compiler/TokenScanner.java |  80 ++++++++++++--
 src/Compiler/TokenType.java    |   2 +-
 src/Compiler/Translator.java   | 197 ++++++++++++++++++++++++++++++---
 src/examples/example.ft        |  27 +++--
 11 files changed, 621 insertions(+), 92 deletions(-)

(limited to 'src')

diff --git a/src/Compiler/Environment.java b/src/Compiler/Environment.java
index 1bb0e88..8ae8724 100644
--- a/src/Compiler/Environment.java
+++ b/src/Compiler/Environment.java
@@ -2,11 +2,13 @@ package Compiler;
 import java.util.HashMap;
 import java.util.Map;
 
+/**
+ * Class to record defined variables during the translation stage
+ */
 public class Environment {
     private final Map<String,Object> variableMap = new HashMap<>();
 
     //Define a variable inside the current environment
-    //Maybe check if variable is already defined?
     public void defineVariable(String name,Object value){
         variableMap.put(name, value);
     }
@@ -20,7 +22,7 @@ public class Environment {
         throw new Error();
     }
 
-    //Get a variable if it is defined, or report an error
+    //Check if a variable is defined, or report an error
     public Boolean checkVariable(Token token){
         if(variableMap.containsKey(token.text)){
             return true;
diff --git a/src/Compiler/ExecuteC.java b/src/Compiler/ExecuteC.java
index fbc7ade..128f541 100644
--- a/src/Compiler/ExecuteC.java
+++ b/src/Compiler/ExecuteC.java
@@ -69,7 +69,6 @@ public class ExecuteC {
 
     public Boolean compileC(){
         try{
-            String s= null;
             Process p;
             if (System.getProperty("os.name").equals("Linux")) {
                 p = Runtime.getRuntime().exec(String.format(
@@ -86,7 +85,7 @@ public class ExecuteC {
             BufferedReader stdError = new BufferedReader(new 
                 InputStreamReader(p.getErrorStream()));
             boolean error=false;
-             while ((s = stdError.readLine()) != null) {
+             while ((stdError.readLine()) != null) {
                  error=true;
              }
              return error;
diff --git a/src/Compiler/Expression.java b/src/Compiler/Expression.java
index 2789462..056019a 100644
--- a/src/Compiler/Expression.java
+++ b/src/Compiler/Expression.java
@@ -2,7 +2,12 @@ package Compiler;
 
 import java.util.List;
 
+//Class for possible expressions in the language
 abstract class Expression {
+
+    /**
+     * Class for representing a binary expression, with two values between an operator
+     */
     static class Binary extends Expression{
 
         final Expression left;
@@ -22,6 +27,9 @@ abstract class Expression {
 
     }
 
+    /**
+     * Class for representing a singlular expression, with one value and one operator
+     */
     static class Singular extends Expression{
 
         final Expression right;
@@ -39,6 +47,9 @@ abstract class Expression {
 
     }
 
+    /**
+     * Class for representing a literal value
+     */
     static class Literal extends Expression{
         final Token value;
         final String type;
@@ -56,6 +67,9 @@ abstract class Expression {
         
     }
 
+    /**
+     * Class for representing an expression between brackets
+     */
     static class BracketedExpression extends Expression{
         final Expression expr;
 
@@ -66,11 +80,12 @@ abstract class Expression {
         @Override
         public String getExpressionType() {
             return "bracket";
-        }
-        
-        
+        }     
     }
 
+    /**
+     * Class for represening an assignment expression
+     */
     static class AssignmentExpression extends Expression{
         final Expression variable;
         final Expression value;
@@ -87,6 +102,9 @@ abstract class Expression {
         }   
     }
 
+    /**
+     * Class for representing a single variable
+     */
     static class Variable extends Expression{
         
         Variable(Token name){
@@ -101,6 +119,9 @@ abstract class Expression {
         
     }
 
+    /**
+     * Class for representing an array variable
+     */
     static class ArrayVariable extends Expression{
         ArrayVariable(Token name,List<Expression> positions){
             this.name=name;
@@ -115,6 +136,9 @@ abstract class Expression {
         final List<Expression> positions;
     }
 
+    /**
+     * Class for representing a function call
+     */
     static class FunctionCall extends Expression{
         FunctionCall(Token name, List<Token> arguments){
             this.arguments=arguments;
@@ -130,5 +154,6 @@ abstract class Expression {
         
     }
 
+    //Abstract method for getting an expression type
     public abstract String getExpressionType();
 }
diff --git a/src/Compiler/Language.java b/src/Compiler/Language.java
index b433b36..5013cfd 100644
--- a/src/Compiler/Language.java
+++ b/src/Compiler/Language.java
@@ -8,7 +8,10 @@ import java.util.List;
 import java.util.Scanner;
 import java.util.ArrayList;
 
-//Base class for the interpreter
+/** 
+ *Base class for running the Compiler 
+ *Can run either from a file, or in an interactive mode
+ */
 public class Language {
 
     static boolean leaveCFile = false;
@@ -17,8 +20,10 @@ public class Language {
     static boolean executeAfter = false;
     static Path sourcefile;
 
+    //Main function for the compiler
     public static void main(String[] args) {
 
+        //Extract required command line arguments
         try {
             sourcefile = Paths.get(args[0]);
         } catch (java.lang.ArrayIndexOutOfBoundsException e) {
@@ -38,6 +43,8 @@ public class Language {
         
         Path initOutPath = Paths.get(args[0]);
         String outname = initOutPath.getName(initOutPath.getNameCount() - 1).toString().split("\\.(?=[^\\.]+$)")[0];
+
+        //Extract optional command line arguments
         ArrayList<String> arrayArgs = new ArrayList<>();
         for (int i = 0; i < args.length; i++) {
             String arg = args[i];
@@ -66,21 +73,24 @@ public class Language {
             return;
         }
 
+        //Run the compiler on the source code
         try {
-            runInterpreter(Files.readString(sourcefile), outname);
+            runCompiler(Files.readString(sourcefile), outname);
         } catch (IOException e) {
             e.printStackTrace();
         }
     }
 
-    //Function to take source code and output the result
-    private static void runInterpreter(String sourceCode, String outName){
+    /** 
+     * Function to take source code, run the compiler and write to C
+     *
+     *  @param sourcecode the full source code as a string
+     *  @param outName the name to write the compiled code to
+     */
+    private static void runCompiler(String sourceCode, String outName){
         //Extract tokens from the source code
         TokenScanner scanner = new TokenScanner();
         List<Token> tokens = scanner.extractTokens(sourceCode);
-        //for (Token token : tokens) {
-        //    System.out.println(token);
-        //}
         if (hadError) return;
 
         //Parse into AST
@@ -98,25 +108,37 @@ public class Language {
         cExecutor.compileAndExecuteC(code, outName, executeAfter, leaveCFile);
     }
 
+    /**
+     * Method for running the compiler in an interactive mode
+     */
     private static void interactiveMode() {
         Scanner input = new Scanner(System.in);
-            String sourceCode = "1";
-            while (sourceCode!=""){
-                System.out.print("Code: ");
-                sourceCode = input.nextLine();
-                runInterpreter(sourceCode, "out");
-                hadError=false;
-            }
-            input.close();
+        String sourceCode = "1";
+        //Run compiler line by line
+        while (sourceCode!=""){
+            System.out.print("Code: ");
+            sourceCode = input.nextLine();
+            runCompiler(sourceCode, "out");
+            hadError=false;
+        }
+        input.close();
     }
     
-    //Basic error reporting
+    /**
+     * Method for displaying an error to the user
+     * @param line the line the error occured on
+     * @param message an error message to display to the user
+     */
     static void displayError(int line,String message){
         hadError=true;
         System.out.println("An error was encountered on line: "+line);
         System.out.println(message);
     }
-    //Basic error reporting
+    /**
+     * Method for displaying error based on a specific token
+     * @param token the token the parser detected the error on
+     * @param message an error message to display to the user
+     */
     static void displayError(Token token,String message){
         hadError=true;
         System.out.println("An error was encountered on line: "+token.line);
@@ -124,6 +146,10 @@ public class Language {
         System.out.println(message);
     }
     
+    /**
+     * Method for getting the helpfile text
+     * @return the text for the helpfile
+     */
     private static String getHelpText(){
         String helpText = "";
         try {
diff --git a/src/Compiler/Parser.java b/src/Compiler/Parser.java
index ae2ed23..433035c 100644
--- a/src/Compiler/Parser.java
+++ b/src/Compiler/Parser.java
@@ -5,17 +5,27 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
-
+/**
+ * Class for parsing the source code, utilising the recursive descent parsing method
+ */
 public class Parser {
     private final List<Token> tokens;
     private int currentToken = 0;
     private final Map<String,String> definedVars = new HashMap<>();
     List<Statement> statements =  new ArrayList<>();
 
+    /**
+     * Constructor of a parser object
+     * @param tokens the list of tokens representing the source code
+     */
     Parser(List<Token> tokens){
         this.tokens=tokens;
     }
 
+    /**
+     * Method for parsing the list of tokens
+     * @return A list of statements for the source code
+     */
     List<Statement> parse(){
         try{
             while (!checkEOF()){
@@ -28,32 +38,53 @@ public class Parser {
         
     }
 
+    /**
+     * Method to extracting the main function, or other functions
+     * @return A statement for a function or main function
+     */
     private Statement functionCalls(){
+
+        //Check for main function definition
         if(matchAndAdvance(TokenType.PROGRAM)){
             matchOrError(TokenType.IDENTIFIER, "Expected program name");
             Token programname = getPreviousToken();
             Statement block = blockStatement(false);
             matchOrError(TokenType.PROGRAM,"Programs must end in 'program'");
             matchOrError(TokenType.IDENTIFIER,"Expected program name");
+
+            //Check program names match
             if(!(getPreviousToken().text.equals(programname.text))){
                 throw error(getPreviousToken(), "Program names do not match");
             }
             return new Statement.MainFunction(block);
-        } else if(matchAndAdvance(TokenType.FUNCTION)){
+
+        //Check for function or subroutine definition
+        } else if(matchAndAdvance(TokenType.FUNCTION)||matchAndAdvance(TokenType.SUBROUTINE)){
+
             String returntype=null;
-            if(matchAndAdvance(TokenType.INT)){
-                returntype="int";
-            } else if (matchAndAdvance(TokenType.REAL)){
-                returntype="real";
-            }else{
-                throw error(getCurrentToken(), "Expected function return type");
+            boolean isfunction=false;
+            //Get function return data type
+            if(getPreviousToken().type==TokenType.FUNCTION){
+                isfunction=true;
+                if(matchAndAdvance(TokenType.INT)){
+                    returntype="int";
+                } else if (matchAndAdvance(TokenType.REAL)){
+                    returntype="real";
+                }else{
+                    throw error(getCurrentToken(), "Expected function return type");
+                }
             }
+
             matchOrError(TokenType.IDENTIFIER, "Expected function name");
             Token name = getPreviousToken();
+
+            //Add function name to the list of defined values
             definedVars.put(name.text, "function");
             matchOrError(TokenType.LEFT_PAREN, "Expected '(");
             List<Expression> arguments=new ArrayList<>();
             List<String> types = new ArrayList<>();
+
+            //Extract the arguments for the function
             if(!matchAndAdvance(TokenType.RIGHT_PAREN)){
                 do{
                     if(matchAndAdvance(TokenType.INT)){
@@ -67,52 +98,85 @@ public class Parser {
                 } while(matchAndAdvance(TokenType.COMMA));
                 matchOrError(TokenType.RIGHT_PAREN, "Expected ')'");
             }
-            Statement block = blockStatement(true);
+
+            Statement block = blockStatement(isfunction);
+
+            //Add the function declaration to the start of the list of statements
             statements.add(0,new Statement.FunctionDeclaration(name,types,returntype));
             return new Statement.Function(name,block,arguments,types,returntype);
         }
-        throw error(getCurrentToken(), "Expected program or function");
+        throw error(getCurrentToken(), "Program must start with program or function");
     }
 
+    /**
+     * Method for extracting a single statement, excluding function definitions
+     * @return any type of statement
+     */
     private Statement statement(){
+        //Check for variable definition
         if(checkToken(TokenType.INT)||checkToken(TokenType.REAL)||checkToken(TokenType.STRING)){
             return declaration();
         }
+
+        //Check for print statement
         else if (matchAndAdvance(TokenType.PRINT)){
             return printStatement();
+
+        //Check for if statement
         }else if (matchAndAdvance(TokenType.IF)){
             return ifStatement();
+
+        //Check for do statement
         }else if (matchAndAdvance(TokenType.DO)){
             return doStatement();
+
+        //Check for return statement
         }else if (matchAndAdvance(TokenType.RETURN)){
             return returnStatement();
         }
+
+        //If no statement matches, assume an expression statement
         return expressionStatement();
     }
 
 
-    //Clean up and reduce code mess
+    /**
+     * Method for parsing a variable definition
+     * @return A variable definition statement
+     */
     private Statement declaration(){
+        //Check if the variable is an integer
         if (matchAndAdvance(TokenType.INT)){
+
+            //Check for array declaration
             if(matchAndAdvance(TokenType.DIMENSION)){
                 return arrayDeclaration("int");
             }
+
             matchOrError(TokenType.DEFINE, ":: Required for variable definition");
             matchOrError(TokenType.IDENTIFIER,"Expected variable name.");
             Token varName = getPreviousToken();
+
+            //Ensure that a variable with the same name has not been defined
             if(definedVars.containsKey(varName.text)){
                 throw error(varName, "Cannot define multiple variables with the same name");
             }else{
                 definedVars.put(varName.text,"int");
                 return new Statement.VariableDeclaration(varName,"int");
             }
+        
+        //Check if the variable is a real type
         } else if (matchAndAdvance(TokenType.REAL)){
+
+            //Check for array declaration
             if(matchAndAdvance(TokenType.DIMENSION)){
                 return arrayDeclaration("real");
             }
             matchOrError(TokenType.DEFINE, ":: Required for variable definition");
             matchOrError(TokenType.IDENTIFIER,"Expected variable name.");
             Token varName = getPreviousToken();
+
+            //Ensure that a variable with the same name has not been defined
             if(definedVars.containsKey(varName.text)){
                 throw error(varName, "Cannot define multiple variables with the same name");
             }else{
@@ -120,12 +184,15 @@ public class Parser {
                 return new Statement.VariableDeclaration(varName,"real");
             }
         
-        //Could be improved significatly when verifiying length is a positive integer
+        //Check if the variable is a string
         } else if (matchAndAdvance(TokenType.STRING)){
+            //Extract the length of the string
             matchOrError(TokenType.LEFT_PAREN, "Length of string must be defined");
             matchOrError(TokenType.LEN, "Length of string must be defined");
             matchOrError(TokenType.EQUALS, "Length of string must be defined");
             Expression length = expression();
+
+            //Ensure the length of the string is a positive integer
             if(!(length instanceof Expression.Literal)){
                 throw error(getCurrentToken(),"String length must be a number");
             }
@@ -135,11 +202,13 @@ public class Parser {
             if((int)((Expression.Literal)length).value.value<1){
                 throw error(getCurrentToken(),"String length must be greater then 0"); 
             }
-            matchOrError(TokenType.RIGHT_PAREN, "Length of string must be defined");
 
+            matchOrError(TokenType.RIGHT_PAREN, "Length of string must be defined");
             matchOrError(TokenType.DEFINE, ":: Required for variable definition");
             matchOrError(TokenType.IDENTIFIER,"Expected variable name.");
             Token varName = getPreviousToken();
+
+            //Ensure that a variable with the same name has not been defined
             if(definedVars.containsKey(varName.text)){
                 throw error(varName, "Cannot define multiple variables with the same name");
             }else{
@@ -150,19 +219,31 @@ public class Parser {
         return null;
     }
 
+    /**
+     * Method to parse an array declaration
+     * @param type The data type of the array
+     * @return A statement representing the array declaration
+     */
     private Statement arrayDeclaration(String type){
         matchOrError(TokenType.LEFT_PAREN,"Expected ')'");
+
+        //Extract the size of the array
         List<Expression> dimensions = new ArrayList<>();
         Expression dimension = expression();
         dimensions.add(dimension);
+
+        //Extract the size of each dimension of the array
         while(matchAndAdvance(TokenType.COMMA)){
             dimension = expression();
             dimensions.add(dimension);
         }
+
         matchOrError(TokenType.RIGHT_PAREN, "Expected ')'");
         matchOrError(TokenType.DEFINE, ":: Required for variable definition");
         matchOrError(TokenType.IDENTIFIER,"Expected variable name.");
         Token varName = getPreviousToken();
+
+        //Ensure that a variable with the same name has not been defined
         if(definedVars.containsKey(varName.text)){
             throw error(varName, "Cannot define multiple variables with the same name");
         }else{
@@ -171,10 +252,18 @@ public class Parser {
         }
     }
 
+    /**
+     * Method for parsing a block of statements
+     * @param isFunction whether the block is for a function and so must contain a return statement
+     * @return a statement representing a block
+     */
     private Statement blockStatement(boolean isFunction){
         boolean hasReturn=false;
         List<Statement> statements = new ArrayList<>();
+
+        //Match statement until an end or else token has been reached
         while(!matchAndAdvance(TokenType.END)&&!checkToken(TokenType.ELSE)){
+            //Ensure the end of the file has not been reached
             if(checkEOF()){
                 throw error(getCurrentToken(),"end missing from block");
             }
@@ -184,15 +273,22 @@ public class Parser {
             }
             statements.add(statement);
         }
+        //Ensure that a function block contains a return statement
         if(isFunction&&!hasReturn){
             throw error(getPreviousToken(), "Function must contain a return statement");
         }
         return new Statement.BlockStatement(statements);
     }
 
+    /**
+     * Method for parsing a print statement
+     * @return A print statement object
+     */
     private Statement printStatement(){
         matchOrError(TokenType.STAR, "Syntax, print *, item1, item2...");
         List<Expression> exprList = new ArrayList<>();
+
+        //Get the list of printed values
         while(matchAndAdvance(TokenType.COMMA)){
             if(checkEOF()){
                 throw error(getCurrentToken(),"reached end of file");
@@ -203,13 +299,18 @@ public class Parser {
         return new Statement.PrintStatement(exprList);
     }
 
-    //Could be cleaned up to handle else statements better
+    /**
+     * Method for parsing an if statement
+     * @return A statement representing an if statement
+     */
     private Statement ifStatement(){
         Expression condition = expression();
         if(matchOrError(TokenType.THEN, "then expected after if statement")){
+            //Extract if block
             Statement ifBlock = blockStatement(false);
             Statement elseBlock=null;
             
+            //Extract else block if required
             if(matchAndAdvance(TokenType.ELSE)){
                 elseBlock=blockStatement(false);
             }
@@ -220,12 +321,19 @@ public class Parser {
         return null;
     }
 
+    /**
+     * Method for parsing a do statement
+     * @return A statement representing a do statement
+     */
     private Statement doStatement(){
+        //Check for do while statement
         if(matchAndAdvance(TokenType.WHILE)){
             return whileStatement();
         }
         Expression variable =expression();
         matchOrError(TokenType.EQUALS, "'=' missing");
+
+        //Extract start, stop, and step variables
         Expression start = expression();
         matchOrError(TokenType.COMMA, " use ',' between values");
         Expression stop = expression();
@@ -239,7 +347,12 @@ public class Parser {
 
     }
 
+    /**
+     * Method to parse a do-while statement
+     * @return a do-while statement object
+     */
     private Statement whileStatement(){
+        //Extract condition
         matchOrError(TokenType.LEFT_PAREN, " missing '(' for do statement condition");
         Expression condition = expression();
         matchOrError(TokenType.RIGHT_PAREN, " missing ')' for do  condition");
@@ -248,18 +361,31 @@ public class Parser {
         return new Statement.DoWhileStatement(condition,codeBlock);
     }
 
+    /**
+     * Method to parse a return statement
+     * @return a return statement object
+     */
     private Statement returnStatement(){
         Expression returnValue = expression();
         return new Statement.ReturnStatement(returnValue);
     }
 
+    /**
+     * Method to parse an expression statement
+     * @return an expression statement object
+     */
     private Statement expressionStatement(){
         Expression expression = assignment();
         return new Statement.ExpressionStatement(expression);
     }
 
+    /**
+     * Method to parse an assignment expression
+     * @return an assignment expression object
+     */
     private Expression assignment(){
         Expression variable = expression();
+        //Check for an equals token
         if (matchAndAdvance(TokenType.EQUALS)){
             Expression assignedvalue = expression();
             return new Expression.AssignmentExpression(variable,assignedvalue);
@@ -267,11 +393,19 @@ public class Parser {
         return variable;
     }
 
+    /**
+     * Method to parse a non-assignment expression
+     * @return an expression object
+     */
     private Expression expression(){
         Expression createdExpression = equality();
         return createdExpression;
     }
 
+    /**
+     * Method to parse an equality comparison expression
+     * @return an expression of rank equality or lower
+     */
     private Expression equality(){
         Expression createdExpression = logical();
         while (matchAndAdvance(TokenType.EQUALITY)){
@@ -282,6 +416,10 @@ public class Parser {
         return createdExpression;
     }
 
+    /**
+     * Method to parse a logical expression
+     * @return an expression of rank logical or lower 
+     */
     private Expression logical(){
         if(matchAndAdvance(TokenType.NOT)){
             Token op = getPreviousToken();
@@ -298,8 +436,13 @@ public class Parser {
         return createdExpression;
     }
 
+    /**
+     * Method to parse a comparison expression
+     * @return an expression of rank comparison or lower 
+     */
     private Expression comparison(){
         Expression createdExpression = term();
+        //Check for different types of comparison
         while (matchAndAdvance(TokenType.GREATER)||matchAndAdvance(TokenType.LESS)||matchAndAdvance(TokenType.GREATER_EQUAL)||matchAndAdvance(TokenType.LESS_EQUAL)){
             Token op = getPreviousToken();
             Expression right = term();
@@ -308,8 +451,13 @@ public class Parser {
         return createdExpression;
     }
 
+    /**
+     * Method to parse a term expression
+     * @return an expression of rank term or lower 
+     */
     private Expression term(){
         Expression createdExpression = factor();
+        //Check for addition or subtraction expression
         while (matchAndAdvance(TokenType.PLUS)||matchAndAdvance(TokenType.MINUS)){
             Token op = getPreviousToken();
             Expression right = factor();
@@ -318,8 +466,13 @@ public class Parser {
         return createdExpression;
     }
 
+    /**
+     * Method to parse a factor expression
+     * @return an expression of rank factor or lower 
+     */
     private Expression factor(){
         Expression createdExpression = primary();
+        //Check for multiplication or division expressions
         while (matchAndAdvance(TokenType.STAR)||matchAndAdvance(TokenType.SLASH)){
             Token op = getPreviousToken();
             Expression right = primary();
@@ -328,26 +481,36 @@ public class Parser {
         return createdExpression;
     }
 
+    /**
+     * Method to parse a primary expression
+     * @return a primary expression 
+     */
     private Expression primary(){
+        //Check for singular numbers
         if (matchAndAdvance(TokenType.NUMBER)){
+            //Check number type
             if(getPreviousToken().value instanceof Integer){
                 return new Expression.Literal(getPreviousToken(),"int");
             } else if(getPreviousToken().value instanceof Double){
                 return new Expression.Literal(getPreviousToken(),"double");
             }
         }
+        //Check for strings
         if (matchAndAdvance(TokenType.STRING)){
             return new Expression.Literal(getPreviousToken(), "string");
         }
-
+        //Check for variable names
         if (matchAndAdvance(TokenType.IDENTIFIER)) {
             Token name= getPreviousToken();
+            //Check for function calls or array assignments
             if(matchAndAdvance(TokenType.LEFT_PAREN)){
+                //Parse array if array with same name has been previously defined
                 if(definedVars.containsKey(name.text)){
                     if(definedVars.get(name.text).equals("array")){
                         List<Expression> positions = new ArrayList<>();
                         Expression position = expression();
                         positions.add(position);
+                        //Parse array positions for each dimension
                         while(matchAndAdvance(TokenType.COMMA)){
                             position = expression();
                             positions.add(position);
@@ -356,7 +519,9 @@ public class Parser {
                         return new Expression.ArrayVariable(name, positions);
                     }
                 }
+                //If not previously declared, assume function call
                 List<Token> arguments = new ArrayList<>();
+                //Parse function call arguments
                 do{
                     matchOrError(TokenType.IDENTIFIER, "Expected argument");
                     Token argumentValue = getPreviousToken();
@@ -369,24 +534,35 @@ public class Parser {
                 matchOrError(TokenType.RIGHT_PAREN, "Expected ')");
                 return new Expression.FunctionCall(name, arguments);
             }
+            //Parse single variable name
             return new Expression.Variable(getPreviousToken());
           }
 
+        //Parse bracketed expressions
         if (matchAndAdvance(TokenType.LEFT_PAREN)){
             Expression expr = expression();
             matchOrError(TokenType.RIGHT_PAREN,"Expected ')'");
             return new Expression.BracketedExpression(expr);
         }
+        //Throw an error if the expression was not recognised
         throw error(getCurrentToken(),"Unknown syntax error");
     }
-
+    /**
+     * Method to move ahead one token
+     */
     private void advanceToken(){
         if (!checkEOF()) {
             currentToken++;
         };
     }
-
+    
+    /**
+     * Method to compare the current token with a given token, and move ahead if a match is found
+     * @param type the token type to compare against
+     * @return if the match was successful
+     */
     private boolean matchAndAdvance(TokenType type){
+        //If the tokens are a match, advance ahead
         if (checkToken(type)) {
             advanceToken();
             return true;
@@ -394,6 +570,12 @@ public class Parser {
         return false;
     }
 
+    /**
+     * Method to check if the current token matches a given token, and throw an error if they do not match
+     * @param type the token type to compare against
+     * @param errorMessage the message to report if a match is not found
+     * @return a boolean to say if a match was successful
+     */
     private boolean matchOrError(TokenType type,String errorMessage){
         if (matchAndAdvance(type)){
             return true;
@@ -401,23 +583,46 @@ public class Parser {
         throw error(getCurrentToken(),errorMessage);
     }
 
+    /**
+     * Method to comapre the current token to a given token
+     * @param type the token type to compare against
+     * @return if the match was successful
+     */
     private boolean checkToken(TokenType type){
         if (checkEOF()) return false;
         return getCurrentToken().type == type; 
     }
 
+    /**
+     * Method to check for the end of the file
+     * @return if the end of the file has been reached
+     */
     private boolean checkEOF(){
         return tokens.get(currentToken).type==TokenType.EOF;
     }
-
+    
+    /**
+     * Method to get the current token
+     * @return the token at the current position
+     */
     private Token getCurrentToken(){
         return tokens.get(currentToken);
     }
 
+    /**
+     * Method to get the previous token
+     * @return the previous token
+     */
     private Token getPreviousToken(){
         return tokens.get(currentToken - 1);
     }
 
+    /**
+     * Method to report an error to the user during parsing
+     * @param token the token the error was detected on
+     * @param message the message to display to the user
+     * @return An error object to stop parsing
+     */
     private Error error(Token token, String message){
         Language.displayError(token ,message);
         return new Error();
diff --git a/src/Compiler/Statement.java b/src/Compiler/Statement.java
index dd3ff04..5e94d35 100644
--- a/src/Compiler/Statement.java
+++ b/src/Compiler/Statement.java
@@ -1,9 +1,14 @@
 package Compiler;
 
 import java.util.List;
-
+/**
+ * Classes for possible statements in the language
+ */
 abstract class Statement {
 
+    /**
+     * Class for the main function of the program
+     */
     static class MainFunction extends Statement{
         MainFunction(Statement block){
             this.block = block;
@@ -18,6 +23,9 @@ abstract class Statement {
         
     }
 
+    /**
+     * Class for representing a function
+     */
     static class Function extends Statement{
         Function(Token name,Statement block,List<Expression> arguments,List<String> argumentTypes,String returnType){
             this.block=block;
@@ -39,6 +47,10 @@ abstract class Statement {
         } 
     }
 
+    /**
+     * Class for representing a function declaration 
+     * needed for compiling to C
+     */
     static class FunctionDeclaration extends Statement{
         FunctionDeclaration(Token name,List<String> argumentTypes,String returnType){
             this.returnType=returnType;
@@ -56,6 +68,9 @@ abstract class Statement {
         } 
     }
 
+    /**
+     * Class for representing a return statement
+     */
     static class ReturnStatement extends Statement{
 
         ReturnStatement(Expression returnValue){
@@ -71,6 +86,9 @@ abstract class Statement {
         
     }
 
+    /**
+     * Class for representing a statement for an expression
+     */
     static class ExpressionStatement extends Statement{
         ExpressionStatement(Expression expr){
             this.expr = expr;
@@ -85,6 +103,9 @@ abstract class Statement {
         }
     }
 
+    /**
+     * Class for representing a block of statements
+     */
     static class BlockStatement extends Statement{
         BlockStatement(List<Statement> statements){
             this.statements=statements;
@@ -99,6 +120,9 @@ abstract class Statement {
         
     }
 
+    /**
+     * Class for representing an if statement
+     */
     static class IfStatement extends Statement{
         IfStatement(Expression condition, Statement ifBlock,Statement elseBlock){
             this.condition=condition;
@@ -116,6 +140,9 @@ abstract class Statement {
         }
     }
 
+    /**
+     * Class for representing a do loop
+     */
     static class DoStatement extends Statement{
         DoStatement(Expression variable, Expression start,Expression stop,Expression step,Statement codeBlock){
             this.variable=variable;
@@ -138,6 +165,9 @@ abstract class Statement {
         }
     }
 
+    /**
+     * Class for representing a do while loop
+     */
     static class DoWhileStatement extends Statement{
         DoWhileStatement(Expression condition,Statement codeBlock){
             this.condition=condition;
@@ -154,7 +184,10 @@ abstract class Statement {
         }
     }
 
-
+    /**
+     * Class for representing a integer or real declaration
+     * 
+     */
     static class VariableDeclaration extends Statement{
         VariableDeclaration(Token name,String type){
             this.name=name;
@@ -172,6 +205,9 @@ abstract class Statement {
 
     }
 
+    /**
+     * Class for representing a string variable declaration
+     */
     static class StringDeclaration extends Statement{
         StringDeclaration(Token name,Expression length){
             this.name=name;
@@ -189,6 +225,9 @@ abstract class Statement {
 
     }
 
+    /**
+     * Class for representing an array declaration
+     */
     static class ArrayDeclaration extends Statement{
         ArrayDeclaration(Token name,String type,List<Expression> dimensions){
             this.name=name;
@@ -207,6 +246,9 @@ abstract class Statement {
 
     }
 
+    /**
+     * Class for representing a print statement
+     */
     static class PrintStatement extends Statement{
         PrintStatement(List<Expression> exprList){
             this.exprList=exprList;
@@ -219,6 +261,6 @@ abstract class Statement {
         }
     }
 
-
+    //Abstract function for getting the statement type
     public abstract String getStatmentType();
 }
diff --git a/src/Compiler/Token.java b/src/Compiler/Token.java
index 50d3804..b6f11a8 100644
--- a/src/Compiler/Token.java
+++ b/src/Compiler/Token.java
@@ -1,15 +1,23 @@
 package Compiler;
 
+/**
+ * Class for storing information about a single token
+ */
 public class Token {
 
-
-    //Stores the token type, the actual text and the runtime object
     public final TokenType type;
     final String text;
     final Object value;
     final int line;
 
 
+    /**
+     * Contructor for a token object
+     * @param type the type of token
+     * @param text the actual text for the token
+     * @param value the value the token represents
+     * @param line the line of code the token is on
+     */
     Token(TokenType type, String text, Object value,int line){
         this.type=type;
         this.text=text;
@@ -17,10 +25,4 @@ public class Token {
         this.line=line;
 
     }
-
-    @Override
-    public String toString() {
-        return type + " " + text + " " + value;
-    }
-
 }
diff --git a/src/Compiler/TokenScanner.java b/src/Compiler/TokenScanner.java
index 02bbbc0..ecb5ad3 100644
--- a/src/Compiler/TokenScanner.java
+++ b/src/Compiler/TokenScanner.java
@@ -5,6 +5,9 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
+/**
+ * The lexical scanner, which takes the source code and extracts a list of token objects
+ */
 public class TokenScanner {
     private String sourceCode;
     List<Token> tokens = new ArrayList<>();
@@ -12,23 +15,33 @@ public class TokenScanner {
     private int currentLoc=0;
     private int line=0;
 
-    //Extract tokens from the source code by reading character by character
+    /**
+     * Method for extracting tokens, checking each character at a time
+     * @param sourceCode the original source code as a string
+     * @return a list of tokens represeting the source code
+     */
     List<Token> extractTokens(String sourceCode){
         this.sourceCode=sourceCode;
+        //Read until the end of the source code as been reached
         while (!checkEOF()){
             tokenStart=currentLoc;
             readToken();
         }
+        //Add a EOF token on the end
         tokens.add(new Token(TokenType.EOF, "", null,line));
         return tokens;
     }
 
-    //Extract a single token
+    /**
+     * Extract a single token
+     */
     private void readToken(){
+        //Get the current character and find the matching token
         char checkChar = sourceCode.charAt(currentLoc);
         switch(checkChar){
 
             case ' ':break;
+            //Advance line when line break found
             case '\n':
                 line++;
                 break;
@@ -45,7 +58,7 @@ public class TokenScanner {
             case ';': createTokenNull(TokenType.SEMI_COLON); break;
             case ',': createTokenNull(TokenType.COMMA); break;
 
-            //Some tokens are multiple characters long (==, <=) etc
+            //Some tokens are multiple characters long
             //so need to check next char as well
             case '=': 
                 if (checkNextChar('=')){
@@ -55,6 +68,7 @@ public class TokenScanner {
                     createTokenNull(TokenType.EQUALS);
                     break;
                 }
+
             case ':': 
                 if (checkNextChar(':')){
                     createTokenNull(TokenType.DEFINE);
@@ -63,6 +77,7 @@ public class TokenScanner {
                     createTokenNull(TokenType.COLON);
                     break;
                 }
+
             case '<': 
                 if (checkNextChar('=')){
                     createTokenNull(TokenType.LESS_EQUAL);
@@ -71,6 +86,7 @@ public class TokenScanner {
                     createTokenNull(TokenType.LESS);
                     break;
                 }
+
             case '>': 
                 if (checkNextChar('=')){
                     createTokenNull(TokenType.GREATER_EQUAL);
@@ -79,6 +95,7 @@ public class TokenScanner {
                     createTokenNull(TokenType.GREATER);
                     break;
                 }
+
             case '"':
                 while(lookAhead()!='"' && !checkEOF()){
                     currentLoc++;
@@ -90,6 +107,7 @@ public class TokenScanner {
                 currentLoc++;
                 createToken(TokenType.STRING, sourceCode.substring(tokenStart, currentLoc+1));
                 break;
+
             case '.':
                 if(checkIsAlpha(lookAhead()))
                     while (checkIsAlpha(lookAhead())){
@@ -112,9 +130,11 @@ public class TokenScanner {
                     } else {
                         Language.displayError(line, "Expected '.' after logical expression");
                     }
+            
+            //Find tokens starting with alphanumeric characters
             default:
 
-                //Check for numer
+                //Check for numeric characters
                 if (checkIsDigit(checkChar)){
                     String type = "int";
                     while (checkIsDigit(lookAhead())){
@@ -134,19 +154,24 @@ public class TokenScanner {
                         createToken(TokenType.NUMBER, Integer.parseInt(sourceCode.substring(tokenStart, currentLoc+1)));
                     }
                 }
+
+                //Check alphabetical character
                 else if (checkIsAlpha(checkChar)){
                     while (checkIsAlpha(lookAhead())){
                         currentLoc++;
                     } 
                     String text = sourceCode.substring(tokenStart, currentLoc+1);
+
+                    //Compare against a list of keywords in the language
                     TokenType type = keywords.get(text);
                     if(type == null){
                         createToken(TokenType.IDENTIFIER, text);
                     } else{
                         createToken(type, text);
                     }
-
+                
                 } else {
+                    //Report an unknown character
                     Language.displayError(line,"Unexpected Character");
                 }
         }
@@ -154,23 +179,37 @@ public class TokenScanner {
 
     }
 
-    //Test for end of file
+    /**
+     * Method to check the end of the source code
+     * @return if the end of the source code has been reached
+     */
     private boolean checkEOF(){
         return currentLoc>=sourceCode.length();
     }
 
-    //Create a token without a value
+    /**
+     * Create a token with a value of null
+     * @param type the token type
+     */
     private void createTokenNull(TokenType type){
         createToken(type, null);
     }
 
-    //Create token
+    /**
+     * Create a token and add to the list
+     * @param type the token type
+     * @param value the value of the token
+     */
     private void createToken(TokenType type, Object value){
         String tokenText = sourceCode.substring(tokenStart, currentLoc+1);
         tokens.add(new Token(type, tokenText, value, line));
     }
 
-    //Check if the next char matches a given char
+    /**
+     * Compare the next character in the source code to a given character
+     * @param matchChar the character to compare against
+     * @return if the character matches
+     */
     private boolean checkNextChar(char matchChar){
         if (checkEOF()){
             return false;
@@ -182,7 +221,10 @@ public class TokenScanner {
         return false;
     }
 
-    //Look at the next char in the source code
+    /**
+     * gets the next character in the source code
+     * @return the next character
+     */
     private char lookAhead(){
         if (currentLoc+1>=sourceCode.length()){
             return ' ';
@@ -192,7 +234,10 @@ public class TokenScanner {
         }
     }
 
-    //Look 2 chars ahead in the source code
+    /**
+     * look at the character two ahead in the source code
+     * @return the character two ahead
+     */
     private char lookTwoAhead(){
         if (currentLoc+2>=sourceCode.length()){
             return ' ';
@@ -202,16 +247,26 @@ public class TokenScanner {
         }
     }
 
-    //Check if a given char is a digit
+    /**
+     * checks if a given character is numerical
+     * @param checkChar the character to check
+     * @return if the character is numerical
+     */
     private boolean checkIsDigit(char checkChar){
         return checkChar>='0' && checkChar<='9';
     }
 
+    /**
+     * check if a character is alphabetical
+     * @param checkChar the character to check
+     * @return  if the character is alphabetical
+     */
     private boolean checkIsAlpha(char checkChar){
         return ('a'<=checkChar && checkChar<='z')||
                ('A'<=checkChar && checkChar<='Z');
     }
 
+    //A hashmap of the keywords used in the language
     private static final Map<String, TokenType> keywords;
 
     static {
@@ -232,5 +287,6 @@ public class TokenScanner {
         keywords.put("program",    TokenType.PROGRAM);
         keywords.put("return",    TokenType.RETURN);
         keywords.put("function",    TokenType.FUNCTION);
+        keywords.put("subroutine",    TokenType.SUBROUTINE);
       }
 }
diff --git a/src/Compiler/TokenType.java b/src/Compiler/TokenType.java
index 6a8f5c0..d3df02e 100644
--- a/src/Compiler/TokenType.java
+++ b/src/Compiler/TokenType.java
@@ -13,7 +13,7 @@ public enum TokenType {
     NUMBER,IDENTIFIER,STRING,
 
     INT,REAL,PRINT,ENDPRINT,IF,THEN,END,ELSE,LEN,DO,WHILE,
-    AND,OR,NOT,DIMENSION,PROGRAM,FUNCTION,RETURN,
+    AND,OR,NOT,DIMENSION,PROGRAM,FUNCTION,RETURN,SUBROUTINE,
 
     EOF
 }
diff --git a/src/Compiler/Translator.java b/src/Compiler/Translator.java
index e0bff23..d520b67 100644
--- a/src/Compiler/Translator.java
+++ b/src/Compiler/Translator.java
@@ -6,16 +6,25 @@ import java.util.List;
 import Compiler.Expression.*;
 import Compiler.Statement.*;
 
-
+/**
+ * Class to take a convert a list of statements into equivalent C source code
+ */
 public class Translator{
 
     List<String> CCode = new ArrayList<>();
     private Environment environment = new Environment();
 
-
+    /**
+     * Method to take a list of statements and convert to C code
+     * @param statements a list of statement objects
+     * @param printC a variable to say if the produced C code should be outputted
+     * @return a list of strings for each line of the produced C code
+     */
     public List<String> compileToC(List<Statement> statements, boolean printC){
+        //Write basic include header files
         CCode.add("#include <stdio.h>");
         CCode.add("#include <string.h>");
+        //Try and write each statement, with a space between each
         try{
             for (Statement statement: statements){
                 evaluateStatement(statement);
@@ -25,6 +34,7 @@ public class Translator{
 
         }
 
+        //Output the C code if desired
         if (printC) {
             for(String t:CCode){
                 System.out.println(t);
@@ -34,7 +44,12 @@ public class Translator{
         return CCode; 
     }
 
+    /**
+     * Method to write a single statement to C
+     * @param statement the statement to write to C
+     */
     private void evaluateStatement(Statement statement){
+        //Call the correct function for each statement type
         switch(statement.getStatmentType()){
             case "main":
                 evalMainFunction((MainFunction)statement);
@@ -78,40 +93,76 @@ public class Translator{
         }
     } 
 
+    /**
+     * Method to write the main function
+     * @param stmt statement to write
+     */
     private void evalMainFunction(MainFunction stmt){
         CCode.add("int main(){");
         evaluateStatement(stmt.block);
         CCode.add("}");
     }
 
+    /**
+     * Method to write a function
+     * @param stmt statement to write
+     */
     private void evalFunction(Function stmt){
-
-        String functionString = stmt.returnType+" "+stmt.name.text+"(";
+        String functionString;
+        if(!(stmt.returnType==null)){
+            functionString = stmt.returnType+" "+stmt.name.text+"(";
+        }else{
+            functionString = "void "+stmt.name.text+"(";
+        }
         boolean first=true;
+        //Write each function argument into C
         for(int i=0;i<stmt.arguments.size();i++){
             if(!first){
                 functionString+=",";
             }
-            environment.defineVariable(evaluateExpression(stmt.arguments.get(i)), stmt.argumentTypes.get(i));
-            functionString+=stmt.argumentTypes.get(i)+" "+evaluateExpression(stmt.arguments.get(i));
+            String type = stmt.argumentTypes.get(i);
+            Expression arg = stmt.arguments.get(i);
+
+            //Define each argument variable in the environment
+            if(type.equals("char*")){
+                environment.defineVariable(evaluateExpression(arg), "string");
+            }else{
+                environment.defineVariable(evaluateExpression(arg), type);
+            }
+
+            functionString+=type+" "+evaluateExpression(arg);
             first=false;
         }
         functionString+="){";
+
+        //Write function block
         CCode.add(functionString);
         evaluateStatement(stmt.block);
         CCode.add("}");
     }
 
+    /**
+     * Method to write a return statement
+     * @param stmt statement to write
+     */
     private void evalReturnStatement(ReturnStatement stmt){
         CCode.add("return "+evaluateExpression(stmt.returnValue)+";");
-
-        
     }
 
+    /**
+     * Method to write a function declaration
+     * @param stmt statement to write
+     */
     private void evalFunctionDeclaration(FunctionDeclaration stmt){
-
-        String functionString = stmt.returnType+" "+stmt.name.text+"(";
+        String functionString;
+        if(!(stmt.returnType==null)){
+            functionString = stmt.returnType+" "+stmt.name.text+"(";
+        }else{
+            functionString = "void "+stmt.name.text+"(";
+        }
         boolean first=true;
+
+        //Write each argument data type
         for(int i=0;i<stmt.argumentTypes.size();i++){
             if(!first){
                 functionString+=",";
@@ -120,22 +171,42 @@ public class Translator{
             first=false;
         }
         functionString+=");";
+
         CCode.add(functionString);
     }
 
+    /**
+     * Method to write an expression statement
+     * @param stmt statement to write
+     */
     private void evalExpressionStatement(ExpressionStatement stmt){
-        evaluateExpression(stmt.expr);
+        String value = evaluateExpression(stmt.expr);
+        CCode.add(value+";");
     }
 
+    /**
+     * Method to write a string declaration statement
+     * @param stringdec statement to write
+     */
     private void evalStringDeclaration(StringDeclaration stringdec){
+        //Add variable to the environment
         environment.defineVariable(stringdec.name.text, "string");
+
+        //Get the size of the string
         int size = (int)((Expression.Literal)stringdec.length).value.value;
+        //Increase the size of the string by 1 to match C code correctly
         size++;
         CCode.add("char "+stringdec.name.text+"["+size+"];");
     }
 
+    /**
+     * Method to write a variable declaration
+     * @param vardec statement to write
+     */
     private void evalVariableDeclaration(VariableDeclaration vardec){
+        //Add variable to the environment
         environment.defineVariable(vardec.name.text, vardec.type);
+        //Write correct data type
         if(vardec.type.equals("int")){
             CCode.add("int "+vardec.name.text+";");
         } else if(vardec.type.equals("real")){
@@ -143,8 +214,15 @@ public class Translator{
         } 
     }
 
+    /**
+     * Method to write an array declaration
+     * @param arraydec statement to write
+     */
     private void evalArrayDeclaration(ArrayDeclaration arraydec){
+        //Add variable to the environment
         environment.defineVariable(arraydec.name.text, arraydec.type);
+
+        //Get the array data type
         String arrayString = "";
         if(arraydec.type.equals("int")){
             arrayString+="int ";
@@ -152,6 +230,8 @@ public class Translator{
             arrayString+="real ";
         } 
         arrayString+=arraydec.name.text;
+
+        //Write each dimension of the array
         for(Expression expr:arraydec.dimensions){
             arrayString+="[";
             arrayString+=evaluateExpression(expr);
@@ -163,23 +243,36 @@ public class Translator{
         
     }
 
+    /**
+     * Method to write a block statement
+     * @param block statement to write
+     */
     private void evalBlockStatement(BlockStatement block){
+        //Write each statement in the block
         for(Statement stmt:block.statements){
             evaluateStatement(stmt);
         }
     }
 
+    /**
+     * Method to write a print statement
+     * @param print statement to write
+     */
     private void evalPrintStatement(PrintStatement print){
         String types="";
         String values="";
         boolean first=true;
+
+        //Write each expression in the print statement
         for(Expression expr:print.exprList){
+            //Don't add a comma for the first value in the print statement
             if(!first){
                 values+=",";
             }else{
                 first=false;
             }
             String exprType="";
+            //Get the data type for each expression
             if(expr instanceof Expression.Literal){
                 exprType=((Expression.Literal)expr).type;
             }
@@ -189,6 +282,8 @@ public class Translator{
             else if (expr instanceof Expression.ArrayVariable){
                 exprType=(String)environment.getVariable((((Expression.ArrayVariable)expr).name));
             }
+
+            //Set the correct data type for the print statement
             if (exprType.equals("int")){
                 types+="%d";
             } else if (exprType.equals("double")){
@@ -196,16 +291,24 @@ public class Translator{
             } else if (exprType.equals("string")){
                 types+="%s";
             }
+            //Add the actual expression value
             values+=evaluateExpression(expr);
         }
+        //Add a line break at the end of the print statement text
         types+="\\n";
         CCode.add("printf(\""+types+"\","+values+");");  
     }
 
+    /**
+     * Method to write an if statement
+     * @param ifstatement statement to write
+     */
     private void evalIfStatement(IfStatement ifstatement){
-        
+        //Write if statement block
         CCode.add("if("+evaluateExpression(ifstatement.condition)+"){");
         evaluateStatement(ifstatement.ifBlock);
+        
+        //Write else block if needed
         if(!(ifstatement.elseBlock==null)){
             CCode.add("}");
             CCode.add("else {");
@@ -214,24 +317,43 @@ public class Translator{
         CCode.add("}");
     }
 
+    /**
+     * Method to write a do statement
+     * @param dostatement statement to write
+     */
     private void evalDoStatement(DoStatement dostatement){
+        //Form the sections of the for loop, assuming the step variable has not been defined
         String start = evaluateExpression(dostatement.variable)+"="+evaluateExpression(dostatement.start);
         String stop = evaluateExpression(dostatement.variable)+"<="+evaluateExpression(dostatement.stop);
         String step = evaluateExpression(dostatement.variable)+"++";
+
+        //Update step variable if needed
         if(!(dostatement.step==null)){
             step = evaluateExpression(dostatement.variable)+"+="+evaluateExpression(dostatement.step);
         }
+    
         CCode.add("for("+start+";"+stop+";"+step+"){");
         evaluateStatement(dostatement.codeBlock);
         CCode.add("}");
     }
 
+    /**
+     * Method to write a do while loop
+     * @param dowhilestatement statement to write
+     */
     private void evalDoWhileStatement(DoWhileStatement dowhilestatement){
         CCode.add("while("+evaluateExpression(dowhilestatement.condition)+"){");
         evaluateStatement(dowhilestatement.codeBlock);
         CCode.add("}");
     }
 
+    /**
+     * Method to write the correct expression object to C
+     * Since an expression is not a full line, the string is returned
+     * Except for assignment expressions
+     * @param expression the expression to write
+     * @return the string representation of an expression
+     */
     private String evaluateExpression(Expression expression){
         switch(expression.getExpressionType()){
             case "binary":
@@ -243,6 +365,7 @@ public class Translator{
             case "bracket":
                 return evaluateBracketedExpression((BracketedExpression)expression);
             case "assign":
+                //Assignments are full lines, so no need to return the string
                 evaluateAssignmentExpression((AssignmentExpression)expression);
                 return "";
             case "arrayvar":
@@ -256,6 +379,11 @@ public class Translator{
         }
     }
 
+    /**
+     * Method to write a binary expression
+     * @param expr the expression to write
+     * @return the string representation of the expression
+     */
     private String evaluateBinaryExpression(Binary expr){
         switch (expr.op.type){
             case PLUS:
@@ -288,6 +416,11 @@ public class Translator{
         return null;
     }
 
+    /**
+     * Method to write a singular expression
+     * @param expr the expression to write
+     * @return the string representation of the expression
+     */
     private String evaluateSingularExpression(Singular expr){
         switch (expr.op.type){
             case NOT:
@@ -298,24 +431,42 @@ public class Translator{
         return null;
     }
 
+    /**
+     * Method to write a literal expression
+     * @param expr the expression to write
+     * @return the string representation of the expression
+     */
     private String evaluateLiteralExpression(Literal expr){
         return (expr.value.value).toString();
     }
 
+    /**
+     * Method to write a bracketed expression
+     * @param expr the expression to write
+     * @return the string representation of the expression
+     */
     private String evaluateBracketedExpression(BracketedExpression expr){
         return "("+evaluateExpression(expr.expr)+")";
     }
 
+    /**
+     * Method to write an assignment expression
+     * @param expr the expression to write
+     */
     private void evaluateAssignmentExpression(AssignmentExpression expr){
         Token name=null;
+        //Get the name of the variable being assigned to
         if(expr.variable instanceof Expression.Variable){
             name = ((Expression.Variable)expr.variable).name;
         }
         else if(expr.variable instanceof Expression.ArrayVariable){
             name = ((Expression.ArrayVariable)expr.variable).name;
         }
+        //Check if the variable has been previously declared
         if(environment.checkVariable(name)){
+            //Check if the value being assigned is a literal or some other expression
             if(expr.value instanceof Expression.Literal){
+                //Strings are handled differently in C, so the string has to be copied into the variable
                 if(((Expression.Literal)expr.value).type.equals("string")){
                     CCode.add("strcpy("+evaluateExpression(expr.variable)+","+evaluateExpression(expr.value)+");");
                 }else{
@@ -328,10 +479,17 @@ public class Translator{
         }
     }
 
+    /**
+     * Method to write an array variable
+     * @param expr the expression to write
+     * @return the string representation of the expression
+     */
     private String evaluateArrayVariable(ArrayVariable expr){
+        //Check the array has been defined
         if(environment.checkVariable(expr.name)){
             String arrayString="";
             arrayString+=expr.name.text;
+            //Write each dimension value
             for(Expression position:expr.positions){
                 arrayString+="[";
                 arrayString+=evaluateExpression(position);
@@ -342,14 +500,26 @@ public class Translator{
         return null;
     }
 
+    /**
+     * Method to write a variable expression
+     * @param expr the expression to write
+     * @return the string representation of the expression
+     */
     private String evaluateVariableExpression(Variable expr){
         return expr.name.text;
     }
 
+    /**
+     * Method to write a function call
+     * @param expr the expression to write
+     * @return the string representation of the expression
+     */
     private String evaluateFunctionCall(FunctionCall expr){
         String functioncall="";
         functioncall+=expr.name.text+"(";
         boolean first=true;
+
+        //Write each argument of the function call
         for(Token arg:expr.arguments){
             if(!first){
                 functioncall+=",";
@@ -360,9 +530,6 @@ public class Translator{
         functioncall+=")";
         return functioncall;
     }
-
-
-
 }
 
 
diff --git a/src/examples/example.ft b/src/examples/example.ft
index 4a4981a..ab5143d 100644
--- a/src/examples/example.ft
+++ b/src/examples/example.ft
@@ -1,15 +1,20 @@
 program example
-int ::test
-int::testtwo
-test=5
-testtwo=7
-int::testthree
-testthree=add(test,testtwo)
-print*,testthree
+int::a
+int::b
+int::c
+a=2+3
+b=3
+c=power(a,b)
+print*,c
 end program example
 
-function int add(int a, int b)
-int::value
-value=a+b
-return value
+
+function int power(int value,int power)
+int::i
+int::final
+final=1
+do i=0,power-1
+final=final*value
+end do
+return final
 end
\ No newline at end of file
-- 
cgit v1.2.3