Commit 9335cf81 authored by pm3g19's avatar pm3g19
Browse files

Interpreter evaluates expression correctly

parent d03edc1a
module ReadCSV where
module CSV where
import System.IO
......@@ -16,4 +16,4 @@ split :: (a -> Bool) -> [a] -> [[a]]
split p l = case span p l of
([], _) -> []
(match, []) -> [match]
(match, _:rem') -> match:split p rem'
\ No newline at end of file
(match, _:rem') -> match:split p rem'
module Eval where
import Types
import Debug
import Data.Maybe
import Data.List
import Debug.Trace
eval, evalFull :: Environment -> Expr -> Expr --only focus on one expression
findVar :: Environment -> SymbolName -> Expr
findVar = notImplemented
findVar e v = fromJust $ lookup v e
addVar :: Environment -> SymbolName -> Expr -> Environment
addVar = notImplemented
debug x = trace ("{{" ++ x ++ "}}")
eval env expr = let (eval', evalFull') = (eval env, evalFull 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 -- TODO not sufficent.
Boolean (evalFull' e1 == evalFull' e2)
Filter -> let (Set inputRecords,predicate) = (eval' $ head inputSets, eval' $ head args) in
Set $ filter ((==Boolean True).(\r -> eval' $ FuncCall predicate [] [r])) $ map eval' inputRecords
IsEqual -> let (e1:e2:_) = args in -- TODO not sufficent.
Boolean (eval' e1 == eval' e2)
(RecordIndex) -> let (Record recordData, Int index) = (eval' $ args !! 0, eval' $ args !! 1) in
recordData !! index
RecordIndex -> let (Record recordData:Int index:_) = (map eval' args) in
recordData !! index
--implement later
--(Map) -> Set $ (map (\r -> FuncCall predicate [] [r]) inputRecords)
......@@ -28,7 +32,7 @@ eval env expr = let (eval', evalFull') = (eval env, evalFull env) in case expr o
newEnv = let (setEnv, argsEnv) = (zip setParams inputSets, zip argParams args) in setEnv ++ argsEnv ++ env
--newEnv = foldl (\env entry@(name, expr) -> addVar env name expr) env --adds entries to environment
-- TODO FIX
(Var name) -> findVar env name
(Var name) -> eval' $ findVar env name
control@(Control lastResult exprs) -> if null exprs then lastResult else eval' $ evalControl1 env control
......@@ -37,5 +41,7 @@ eval env expr = let (eval', evalFull') = (eval env, evalFull env) in case expr o
evalControl1 :: Environment -> Expr -> Expr
evalControl1 env (Control _ (currentExpr:exprs)) = let output = eval env currentExpr in Control output exprs
evalFull = eval -- evaluates expression fully (not just weak head normal form)
evalFull = eval
--evalFull env (Set xs) = Set (map (eval env) xs) -- evaluates expression fully (not just weak head normal form)
--evalFull _ e = e
--TODO implement properly
\ No newline at end of file
......@@ -2,9 +2,10 @@ import Types
import Debug
import Eval
import System.IO
import ReadCSV
import CSV
import Lexer
import Parser
import Debug.Trace
parse :: String -> Program
parse = parseSource.alexScanTokens
......@@ -19,9 +20,8 @@ interpret sourceFName = do
let program = parse source -- main abstract syntax tree
(env, mainExpr) <- prepare program
print $ "Main expression " ++ show mainExpr
let output = eval env mainExpr
print $ "Output " ++ show output
let finalOutput = evalFinal output
let finalOutput = eval env mainExpr
print $ "Final outupt: " ++ show finalOutput
showFinal finalOutput
prepare :: Program -> IO (Environment, Expr) -- takes in the AST for the program, reads the csv files and prepares the environment based on the CSV files
......@@ -36,17 +36,18 @@ prepare (inputSets,instructions) = do
evalFinal :: Expr -> Expr -- whnf set to ready set
evalFinal = evalFull []
evalFinal expr = trace ("Called with: " ++ show expr) (evalFull [] expr)
showFinal :: Expr -> IO ()
showFinal = (print2DList.sort2DListLex.setTo2DList)
setTo2DList :: Expr -> [[String]]
setTo2DList = notImplemented
setTo2DList (Set records) = map (map (\(String s) -> s).(\(Record list) -> list)) records
sort2DListLex = id -- TODO change this
print2DList = notImplemented
print2DList :: [[String]] -> IO ()
print2DList = notImplemented
--------------------------------------------
loadInputFile :: SymbolName -> IO Expr
loadInputFile name = do
......
......@@ -296,10 +296,10 @@ happyReduce_11 = happyReduce 4 10 happyReduction_11
happyReduction_11 (_ `HappyStk`
(HappyTerminal (TokenNat happy_var_3)) `HappyStk`
_ `HappyStk`
_ `HappyStk`
(HappyAbsSyn10 happy_var_1) `HappyStk`
happyRest)
= HappyAbsSyn10
(FuncCall (PredefFunc RecordIndex) [] [Types.Int happy_var_3]
(FuncCall (PredefFunc RecordIndex) [] [happy_var_1, Types.Int happy_var_3]
) `HappyStk` happyRest
happyReduce_12 = happySpecReduce_1 10 happyReduction_12
......
......@@ -52,7 +52,7 @@ Func : '\\' '(' VarNames ')' "->" Expr {FuncDef [] $3 $6}
Expr : Expr "==" Expr {FuncCall (PredefFunc IsEqual) [] [$1, $3]}
| Expr'['Nat']' {FuncCall (PredefFunc RecordIndex) [] [Types.Int $3]}
| Expr'['Nat']' {FuncCall (PredefFunc RecordIndex) [] [$1, Types.Int $3]}
| Str {Types.String $1}
| VarName {Var $1}
| Record {$1}
......
......@@ -2,4 +2,4 @@
SampleSet
.out
filter[A](\(r) -> r[1] == "hello")
\ No newline at end of file
filter[SampleSet](\(r) -> r[0] == "hello")
\ No newline at end of file
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment