diff --git a/Debug.hs b/Debug.hs
new file mode 100644
index 0000000000000000000000000000000000000000..6c66e0c069b2ce8c7fae62ccb78ef2ff8dc1ef94
--- /dev/null
+++ b/Debug.hs
@@ -0,0 +1,2 @@
+module Debug where
+notImplemented = error "Not implemented yet"
diff --git a/Eval.hs b/Eval.hs
new file mode 100644
index 0000000000000000000000000000000000000000..712aeffed0d73b9972a08678c1be2b06dd4e8293
--- /dev/null
+++ b/Eval.hs
@@ -0,0 +1,27 @@
+eval :: ResultEnvironment -> Expr -> Expr --only focus on one expression
+type Environment = ResultEnvironment
+findVar :: Environment -> SymbolName -> Expr
+findVar = notImplemented
+addVar :: Environment -> SymbolName -> Expr -> Environment
+
+eval env expr = let eval' = eval env in case expr of -- evaluates expression to weak-head normal form (i.e. top level data structure is not a FuncCall)
+    FuncCall func inputSets args -> case func of
+        (PredefFunc f) -> case f of
+            (Filter) -> let (Set inputRecords,predicate) = (eval' $ head inputSets, eval' $ head args) in
+                Set $ filter ((==Boolean True).eval')(map (\r -> FuncCall predicate [] [r]) inputRecords) -- result is weak-head normal form
+                --Set $ map (eval env) (map (\r -> FuncCall predicate [] [r]) inputRecords) # don't evaluate last step
+
+            (IsEqual) -> let (e1:e2:_) = args in
+                Boolean (eval' e1 == eval' e2)
+
+            (RecordIndex) -> let (Record recordData, Int index) = (eval' $ args !! 0, eval' $ args !! 1) in
+                recordData !! index
+
+            --implement later
+            --(Map) -> Set $ (map (\r -> FuncCall predicate [] [r]) inputRecords)
+        (FuncDef setParams argParams body) -> eval new_env body
+            where
+                newEnv = foldl (\env entry@(name, expr) -> addVar env name expr) env --adds entries to environment
+                -- TODO FIx
+    (Var name) -> findVar env name
+    _ -> expr
diff --git a/Interpreter.hs b/Interpreter.hs
new file mode 100644
index 0000000000000000000000000000000000000000..2fe210e256f73daac1fd68b70bd35e4c8351a44c
--- /dev/null
+++ b/Interpreter.hs
@@ -0,0 +1,31 @@
+import Types
+import Debug
+
+type Control = (ResultEnvironment, [Expr])
+type ResultEnvironment = [(SymbolName, Expr)] -- (result of last calculation, other bindings e.g. let statements)
+
+prepare :: Program -> IO Control -- takes in the AST for the program, reads the csv files and prepares the environment based on the CSV files
+prepare (inputSets,instructions) = zipM (environment, return instructions)
+    where environment = fmap (zip inputSets) $ loadInputFiles inputSets
+
+---eval :: Control -> Expr -- fully evaluates the program, returning a set
+zipM (a,b) = do
+    a' <- a
+    b' <- b
+    return (a',b')
+
+--pairmap f s = (s, fs)
+
+--------------------------------------------
+
+programStep :: Control -> Control -- updates environment and list
+programStep = notImplemented
+
+
+--------------------------------------------
+
+loadInputFiles :: [String] -> IO [[String]]
+loadInputFiles = mapM readCSV
+
+readCSV :: FilePath -> IO [[String]]
+readCSV _ = error ""
\ No newline at end of file