diff --git a/ReadCSV.hs b/CSV.hs similarity index 86% rename from ReadCSV.hs rename to CSV.hs index ba3486a07ecca1db0d18ae5051d94ea7fceaaacd..43f486d4191d639b4c39ea35e5cf62c2f1de7ae5 100644 --- a/ReadCSV.hs +++ b/CSV.hs @@ -1,4 +1,4 @@ -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' diff --git a/Eval.hs b/Eval.hs index 8e95c1f92dc34cd932b1766d4325ccd3f58fe136..b5f605122c67053860f36612a8769c48e4763388 100644 --- a/Eval.hs +++ b/Eval.hs @@ -1,25 +1,29 @@ 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 diff --git a/Interpreter.hs b/Interpreter.hs index ad557b3597a4cf9406649c61e0ab61950f9df0ab..058a4f2ac0c534bb4fe9b59da7d2d7200c8ae769 100644 --- a/Interpreter.hs +++ b/Interpreter.hs @@ -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 diff --git a/Parser.hs b/Parser.hs index 785d1c518cb920036975ef814da7e524098e9c50..c0bd9cc10606a5929f2ed9278bb2db15e0c7c398 100644 --- a/Parser.hs +++ b/Parser.hs @@ -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 diff --git a/Parser.y b/Parser.y index 5bcbb6773ffd95952e7f9fa3eaaefb672c6a5870..030a148fcbe77c70594bebb70d4237544c66492b 100644 --- a/Parser.y +++ b/Parser.y @@ -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} diff --git a/sampleprogram.txt b/sampleprogram.txt index 8c5dc4adf60d70127ca1ebc601f41fb2532ebbf2..f7c9aacf95505e416def94eba4ca81d2b2eee682 100644 --- a/sampleprogram.txt +++ b/sampleprogram.txt @@ -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