diff --git a/src/Eval.hs b/src/Eval.hs
index a081f997b22b268a621178fcc8651fa5dae7a597..5e1e941b3c27ea0b03b2e1d35438d86aeb20ecf4 100644
--- a/src/Eval.hs
+++ b/src/Eval.hs
@@ -34,12 +34,18 @@ eval env expr = let (eval', evalFull') = (eval env, evalFull env) in case expr o
                 [Set l1, Set l2] -> Set $ [ x `concatRecord` y | x <- l1, y <- l2]
                 _ -> error "X product takes in two sets"
             
+            (ComparisonFunc op) -> case args' of
+                [e1, e2] -> Boolean $ e1 `op` e2
+                _ -> error "Comparison must take in two arguments"
+
             (BooleanFunc op) -> case args' of 
                 [Boolean e1, Boolean e2] -> Boolean (e1 `op` e2)
-                _ -> error "Boolean function takes in two arguments."
+                _ -> error "Boolean function AND/OR takes in two arguments."
 
-            RecordIndex -> eval' $ case args' of 
+            RecordIndex -> eval' $ case args' of --TODO rename
                 [Record recordData,Int index] -> recordData `listAtIndex` index
+                [String stringData,Int index] -> String [stringData `listAtIndex` index]
+
             RecordSelect -> case args' of
                 (Record recordData: indexes ) -> Record filteredList
                     where
@@ -48,31 +54,52 @@ eval env expr = let (eval', evalFull') = (eval env, evalFull env) in case expr o
                         filteredList = map (eval'.listAtIndex recordData) indexesRaw
                         checkInt (Int i) = i
                         checkInt _ = error "Arguments to index record must be integers"
+                
+                (String stringData: indexes ) -> String filteredList
+                    where
+                        indexesRaw = map checkInt indexes
+                        --filteredList = map (eval'.(stringData !!)) indexesRaw
+                        filteredList = map (listAtIndex stringData) indexesRaw
+                        checkInt (Int i) = i
+                        checkInt _ = error "Arguments to index list must be integers"
                         
-
+                
                         {-numberedElems = zip [1..] recordData :: [(Int, Expr)]
                         filtered = filter ((`elem` indexesRaw).fst) numberedElems :: [(Int, Expr)]
                         filteredList = map snd filtered :: [Expr]-}
+
+
                 
             IsEmpty -> case head args' of
                 (String a) -> Boolean $ null a
-                _ -> error "IsEmpty operates on a string"
+                _ -> error "'isEmpty' operates on a string"
                 
             NotEmpty -> case head args' of
                 (String a) -> Boolean $ (not.null) a
-                _ -> error "notEmpty operates on a string"
+                _ -> error "'notEmpty' operates on a string"
 
             Contains -> case args' of
                 [String a, String b] -> Boolean $ b `isSubList` a
-                _ -> error "Arguments to 'Contains' must be two strings."
+                _ -> error "Arguments to 'contains' must be two strings."
 
             Plus -> case args' of
                 [String a, String b] -> String (a ++ b)
                 [Record a, Record b] -> Record (a ++ b)
                 _ -> error "Arguments to '+' must either be two strings or two records"
 
+            Split -> case args' of
+                [String a, Int i] -> if (i <= length a) then splitRecord else error "Splitat: index outside of range"
+                    where
+                        splitRecord = let (s1, s2) = splitAt i a in Record [String s1, String s2]
+                _ -> error "'split' argument error"
+
             Not -> case args' of
                 [Boolean exp1] -> Boolean $ not exp1
+
+            Length -> case args' of
+                [String a] -> Int $ length a
+                _ -> error "'length' only operates on a String"
+
         (FuncDef setParams argParams body) -> eval newEnv body
             where
                 newEnv = let (setEnv, argsEnv) = (zip setParams inputSets, zip argParams args) in setEnv ++ argsEnv ++ env
diff --git a/src/Lexer.x b/src/Lexer.x
index 1cab7571e7ce16a73be0c93358d4a0f99d13ab28..d710ded231e57e00a80a818915f55ce721b20348 100644
--- a/src/Lexer.x
+++ b/src/Lexer.x
@@ -26,6 +26,8 @@ let                                {\p s -> TokenLet p }
 if                                 {\p s -> TokenIf p }
 else                               {\p s -> TokenElse p }
 then                               {\p s -> TokenThen p }
+and                                {\p s -> TokenBoolAND p  }
+or                                 {\p s -> TokenBoolOR p  }
 \.in                               {\p s -> TokenInSet p }
 \.out                              {\p s -> TokenOutSet p }
 \[                                 {\p s -> TokenLeftSqBracket p }
@@ -36,7 +38,7 @@ then                               {\p s -> TokenThen p }
 "=="                               {\p s -> TokenisEqual p }
 "/="                               {\p s -> TokenisNotEqual p }
 "+"                                {\p s -> TokenPlus p }
-\=                                {\p s -> TokenEqual p }
+\=                                 {\p s -> TokenEqual p }
 \(                                 {\p s -> TokenLeftBracket p }
 \)                                 {\p s -> TokenRightBracket p }
 \:                                 {\p s -> TokenCol p }
@@ -47,13 +49,17 @@ then                               {\p s -> TokenThen p }
 x                                  {\p s -> TokenXProduct p }
 xx                                 {\p s -> TokenXXProduct p }
 map                                {\p s -> TokenMap p }
+length                             {\p s -> TokenLen p }
+\!                                 {\p s -> TokenWithout p }
+split                              {\p s -> TokenSplit p }
+reverse                            {\p s -> TokenReverse p }
+\>                                 {\p s -> TokenGthan p }
+\<                                  {\p s -> TokenLthan p }
 $lower [$lower $digit \_ \']*      {\p s -> TokenVarName p s }
 $upper[$alpha $digit \_ \']*       {\p s -> TokenSetName p s }
 --$posDigit$digit*                 {\p s -> TokenPosNat p (read s) }
 $digit+                            {\p s -> TokenNat p (read s) }
 \"[$alpha $digit]+\"               {\p s -> TokenString p (init.tail $ s) }
-AND                                {\p s -> TokenBoolAND p  }
-OR                                 {\p s -> TokenBoolOR p  }
 
 
 {
@@ -96,7 +102,13 @@ data Token  =
     TokenThen  AlexPosn          |
     TokenEqual   AlexPosn        |
     TokenBoolAND AlexPosn        |
-    TokenBoolOR AlexPosn
+    TokenBoolOR AlexPosn         |
+    TokenLen AlexPosn            |
+    TokenWithout AlexPosn        |
+    TokenSplit AlexPosn         |
+    TokenReverse AlexPosn        |
+    TokenGthan AlexPosn         |
+    TokenLthan AlexPosn         
     deriving  (Eq, Show)
 
 
@@ -138,4 +150,10 @@ pos token = case token of
     (TokenIf p) -> p
     (TokenThen p) -> p
     (TokenEqual p) -> p
+    (TokenLen p) -> p
+    (TokenWithout p) -> p
+    (TokenSplit p) -> p
+    (TokenReverse p) -> p
+    (TokenGthan p) -> p
+    (TokenLthan p) -> p
 }
\ No newline at end of file
diff --git a/src/Parser.y b/src/Parser.y
index 39c3dafaac67d43faa0971b7b4828fbd9c2ac65a..0ba42b8e6b5884e5a3f23d291722e0335c0ebc85 100644
--- a/src/Parser.y
+++ b/src/Parser.y
@@ -50,18 +50,28 @@ import CSV
 	else            { TokenElse _}
 	then            { TokenThen _}
 	'='             { TokenEqual _}
-	or		        { TokenBoolAND _ }
-	and		        { TokenBoolOR _ }
+	and		        { TokenBoolAND _ }
+	or		        { TokenBoolOR _ }
+	length          { TokenLen _}
+	'!'             { TokenWithout _}
+	split           {TokenSplit _}
+	reverse         {TokenReverse _}
+	'>'             {TokenGthan _}
+	'<'             {TokenLthan _}
 	
 
-%left FUNCCALL
-%right INDEX
-%right map filter FUNCCALL
 
-%left '+'
-%left '=='
+%left "->"
 %left or
 %left and
+%left '<' '>'
+%left '+'
+%left "=="
+%left Str
+%left FUNCCALL
+%left PAREN
+%left '[' '(' '{'
+%nonassoc ';'
 
 %%
 
@@ -72,21 +82,24 @@ SetDecls : SetDecl {[$1]}
 	| SetDecls','SetDecl {$3:$1}
 
 Instructions : Expr ';'               {[$1]}
-            | Expr';' Instructions   {$1:$3}
+            | Expr ';' Instructions   {$1:$3}
 
 Expr : 
-      Expr '('Exprs')'  %prec FUNCCALL             {FuncCall $1 [] $3}
-	 | Expr '{' Exprs '}' '('Exprs')' {FuncCall $1 $3 $6}
+      Expr '('Exprs')' %prec FUNCCALL              {FuncCall $1 [] $3} 
+	 | Expr '{' Exprs '}' '('Exprs')' %prec FUNCCALL  {FuncCall $1 $3 $6}
      | Expr "==" Expr                   {FuncCall (PredefFunc IsEqual) [] [$1, $3]}
+     | Expr '>' Expr                   {compareExpr (>) $1 $3}
+     | Expr '<' Expr                   {compareExpr (<) $1 $3}
 --     | Expr "/=" Expr                   {FuncCall (PredefFunc IsNotEqual) [] [$1, $3]}
      | Expr x Expr	             {FuncCall (PredefFunc XProduct) [$1, $3] []}
      | Expr '+' Expr	             {FuncCall (PredefFunc Plus) [$1, $3] []}
-     | Expr'['Expr']'   %prec INDEX                   {FuncCall (PredefFunc RecordIndex) [] [$1, $3]}
-	 | Expr'['Expr','Exprs']'              {FuncCall (PredefFunc RecordSelect) [] ($1:$3:$5) }
-     | '['Exprs']'                      {Record $2}
-	 | Str                               {Types.String $ stripWhitespace $1}
-	 | '\\' '(' VarNames ')' "->" Expr   { FuncDef [] $3 $6 }
-	 | if '('Expr')' then Expr else Expr       {If $3 $6 $8}
+     | Expr'['Expr']'                                        {FuncCall (PredefFunc RecordIndex) [] [$1, $3]}
+	 | Expr'['Expr','Exprs']'                                {FuncCall (PredefFunc RecordSelect) [] ($1:$3:$5) }
+     | '['Exprs']'                                           {Record $2}
+     | '('Expr')'   %prec PAREN                              {$2}
+	 | Str                                                   {Types.String $ stripWhitespace $1}
+	 | '\\' '(' VarNames ')' "->" Expr                       { FuncDef [] $3 $6 }
+	 | if '('Expr')' then Expr else Expr      {If $3 $6 $8}
 	 | let SetName '=' Expr            {Let True $2 $4}
 	 | let VarName '=' Expr            {Let False $2 $4}
      | VarName                           {Var $1}
@@ -96,14 +109,21 @@ Expr :
 	 | PredefFunc                       {PredefFunc $1}
 	 | Expr or Expr                     {booleanExpr (||) $1 $3}
      | Expr and Expr                    {booleanExpr (&&) $1 $3}
+--	 | length Expr                      {FuncCall (PredefFunc length) [] [$2]}
+--	 | Expr contains Expr               {FuncCall (PredefFunc contains) [] [$1, $3]}
+--	 | Expr '!' Expr                    {FuncCall (PredefFunc without) [] [1, $3]}
+--	 | split Expr Expr 
 	 
 PredefFunc : isEmpty {IsEmpty}
 	| filter {Filter}
 	| contains {Contains}
 	| isEmpty {IsEmpty}
+	| length {Length}
+	| split {Split}
 --	| nEmpty {IsEmpty}
 	| map {Map}
 	| not {Not}
+--	| without {Without}
 --	| and {And}
 --	| or  {Or}
 --	| zip {Zip}
diff --git a/src/Types.hs b/src/Types.hs
index 9e5d4bc63b6fbfdda69415d9187cc54b7e1e0103..473898f9046ec79ad4ac2c6c652ee600f6e69920 100644
--- a/src/Types.hs
+++ b/src/Types.hs
@@ -12,9 +12,11 @@ data PredefFunc = XProduct | XXProduct | IsEqual | IsNotEqual | Plus --operators
     | RecordIndex -- [] operator
     | RecordSelect
     | IsEmpty | NotEmpty | Contains   -- string functions
+    | Split
     | Length
     | Not
     | BooleanFunc (Bool -> Bool -> Bool)
+    | ComparisonFunc (Expr -> Expr -> Bool)
     --TODO others:reverse
 instance Show PredefFunc where
     show XProduct = "XProduct"
@@ -32,6 +34,8 @@ instance Show PredefFunc where
     show Length = "Length"
     show Not = "Not"
     show (BooleanFunc _) = "BooleanFunc"
+    show (ComparisonFunc _) = "CompFunc"
+    show (_) = "Unknown"
 
 
 --n.b. these definitions do not enforce type checking! The use of any function or operator will be associated with a FuncCall.
@@ -58,6 +62,7 @@ data Expr = Control Expr [Expr] -- result of last computation, sequence of instr
 --    | Nat Int 
     deriving (Show)
 booleanExpr func e1 e2 = FuncCall (PredefFunc $ BooleanFunc func) [] [e1,e2]
+compareExpr func e1 e2 = FuncCall (PredefFunc $ ComparisonFunc func) [] [e1,e2]
     
 instance Eq Expr where
     --(Record r1) == (Record r2) = and (zipWith (==) r1 r2)
@@ -67,4 +72,15 @@ instance Eq Expr where
     (Boolean b1) == (Boolean b2) = b1 == b2
     (Int v1) == (Int v2) = v1 == v2
     _ == _ = error "Comparison of incompatible types"
+
+instance Ord Expr where
+    --(String i) > (String j) = i > j
+    (String i) <= (String j) = i <= j
+
+    --(Int i) > (Int j) = i > j
+    (Int i) <= (Int j) = i <= j
+
+    --_ < _ = error "Invalid comparison"
+    --_ > _ = error "Invalid comparison"
+
 data Parameter = NamedParam SymbolName | TupleMatch [SymbolName]
\ No newline at end of file