Skip to content
Snippets Groups Projects
Commit 464c5249 authored by pm3g19's avatar pm3g19
Browse files

Updated stack project to latest code

parent 54752cc3
No related branches found
No related tags found
No related merge requests found
LICENSE 0 → 100644
Copyright Author name here (c) 2021
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following
disclaimer in the documentation and/or other materials provided
with the distribution.
* Neither the name of Author name here nor the names of other
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1 ,5 ,4 ,
2 , ,2 ,
3 ,7 ,1 ,2
4 ,8 , ,
\ No newline at end of file
David , Beckham
Pele ,
Diego , Maradona
Cristiano, Ronaldo
Ronaldinho ,
\ No newline at end of file
1 ,6 ,4 ,7
2 ,8 ,5 ,3
2 , , ,1
4 , ,2 ,3
\ No newline at end of file
1 ,5 ,4 ,0
2 , 0,2 ,0
3 ,7 ,1 ,2
4 ,8 , 0,0
\ No newline at end of file
# csvql
1 ,6 ,4 ,7
2 ,8 ,5 ,3
2 ,0,0,1
4 ,0,2 ,3
\ No newline at end of file
import Distribution.Simple
main = defaultMain
module Main where
import Interpreter
import Control.Exception
import System.Environment
main :: IO ()
main = do
args <- getArgs
case args of
--("default":_) -> catch (interpret "/home/patryk/dev/plc/extra-problems/ex1.cql") (errorFunc)
(srcname:_) -> catch (interpret srcname) (errorFunc)
_ -> printErr "No source file specified."
errorFunc :: ErrorCall -> IO ()
errorFunc = printErr.show
\ No newline at end of file
cabal-version: 1.12
-- This file has been generated from package.yaml by hpack version 0.34.4.
--
-- see: https://github.com/sol/hpack
--
-- hash: 3fe644e4d9e0509e20b1fd83f282a8b9332a2b4de3947af78367746e7406ca53
name: csvql
version: 0.1.0.0
description: Please see the README on GitHub at <https://github.com/githubuser/csvql#readme>
author: Jeffrey,Patryk and Maram
copyright: 2021 Jeffrey,Patryk and Maram
license: BSD3
license-file: LICENSE
build-type: Simple
extra-source-files:
README.md
ChangeLog.md
library
exposed-modules:
CSV
Debug
Eval
Interpreter
Lexer
Parser
Types
other-modules:
Paths_csvql
hs-source-dirs:
src
build-depends:
array
, base >=4.7 && <5
default-language: Haskell2010
executable csvql-exe
main-is: Main.hs
other-modules:
Paths_csvql
hs-source-dirs:
app
ghc-options: -threaded -rtsopts -with-rtsopts=-N
build-depends:
array
, base >=4.7 && <5
, csvql
default-language: Haskell2010
test-suite csvql-test
type: exitcode-stdio-1.0
main-is: Spec.hs
other-modules:
Paths_csvql
hs-source-dirs:
test
ghc-options: -threaded -rtsopts -with-rtsopts=-N
build-depends:
array
, base >=4.7 && <5
, csvql
default-language: Haskell2010
name: csvql
version: 0.1.0.0
#github: "https://git.soton.ac.uk/plc1/comp2212-cw-2021"
license: BSD3
author: "Jeffrey,Patryk and Maram"
maintainer: ""
copyright: "2021 Jeffrey,Patryk and Maram"
extra-source-files:
- README.md
- ChangeLog.md
# Metadata used when publishing your package
# synopsis: Short description of your package
# category: Web
# To avoid duplicated efforts in documentation and dealing with the
# complications of embedding Haddock markup inside cabal files, it is
# common to point users to the README.md file.
description: Please see the README on GitHub at <https://github.com/githubuser/csvql#readme>
dependencies:
- base >= 4.7 && < 5
- array
library:
source-dirs: src
executables:
csvql-exe:
main: Main.hs
source-dirs: app
ghc-options:
- -threaded
- -rtsopts
- -with-rtsopts=-N
dependencies:
- csvql
tests:
csvql-test:
main: Spec.hs
source-dirs: test
ghc-options:
- -threaded
- -rtsopts
- -with-rtsopts=-N
dependencies:
- csvql
.in
A:2, # declare input files and their numbers of cols in .in section
B:2
.out # statements for the query are in .out section
A x B; # returns the cartesian product of the two sets (conjunction)
\ No newline at end of file
.in
A:3
.out
filter( \(r) -> r[1] == r[2]);
map (\(r) -> r[3,1]);
\ No newline at end of file
.in
P: 4,
Q: 4
.out
P x Q;
filter(\(r) -> r[1] == r[5]);
let f = \(a,y) -> if (isEmpty(a)) then y else a;
map (\(r) -> [r[1], f(r[2], r[6]), f(r[3], r[7]), f(r[4], r[8])]);
\ No newline at end of file
.in
P42 :2
.out
filter (\(r) -> not(isEmpty(r[2]) ) );
\ No newline at end of file
.in
A:1
.out
map{A}(\(r) -> [r[1],"0",r[1]] );
\ No newline at end of file
run.sh 0 → 100755
#!/bin/bash
.stack-work/dist/x86_64-linux-tinfo6/Cabal-3.2.1.0/build/csvql-exe/csvql-exe $@
\ No newline at end of file
module CSV where
import System.IO
import Data.List
readCSV :: FilePath -> IO [[String]]
readCSV fname = do
str <- readFile fname
return $ readCSVString str
readCSVString :: String -> [[String]]
readCSVString whole = [splitElem ',' (line++" " ) | line <- splitElem '\n' whole]
splitElem :: Eq a => a -> [a] -> [[a]]
splitElem elem = split (/=elem)
split :: (a -> Bool) -> [a] -> [[a]]
split p l = case span p l of
([], _) -> []
(match, []) -> [match]
(match, _:rem') -> match:split p rem'
print2DList :: [[String]] -> IO ()
print2DList = putStrLn.toCSVString
toCSVString :: [[String]] -> String
--F: use the function lines!
toCSVString list = let lines = map (',' `join`) list in '\n' `join` lines
join :: a -> [[a]] -> [a]
join _ [] = []
join a l = foldr1 (\s1 s2 -> s1 ++ a:s2) l
sort2DListLex :: [[String]] -> [[String]]
sort2DListLex = sort
stripWhitespace = stripTrailingWhitespace.dropWhile (==' ')
stripTrailingWhitespace (' ':xs) = let remainder = stripTrailingWhitespace xs in
if null remainder then [] else ' ':remainder
stripTrailingWhitespace (x:xs) = x : stripTrailingWhitespace xs
stripTrailingWhitespace [] = []
\ No newline at end of file
module Debug where
notImplemented = error "Not implemented yet"
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 -> Maybe Expr
findVar e v = 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 -> let (func', inputSets', args') = (eval' func, map eval' inputSets, map eval' args) in case func' of
(PredefFunc f) -> case f of
Filter -> case (inputSets', args') of
([Set inputRecords], [predicate]) -> let func = (\r -> eval' $ FuncCall predicate [] [r]) in
Set $ filter ((==Boolean True).func) inputRecords
_ -> error "Filter argument error"
Map -> eval' $ case(inputSets', args') of
([Set records], [lambda]) -> Set (map (\record -> FuncCall lambda [] [record]) records)
_ -> error "Map argument error"
IsEqual -> case args' of -- TODO not sufficent.
[e1, e2] -> Boolean (e1 == e2)
_ -> error "isEqual argument error"
XProduct -> eval' $ case inputSets' of
[Set l1, Set l2] -> Set $ [ x `concatRecord` y | x <- l1, y <- l2]
_ -> error "X product takes in two sets"
(BooleanFunc op) -> case args' of
[Boolean e1, Boolean e2] -> Boolean (e1 `op` e2)
_ -> error "Boolean function takes in two arguments."
RecordIndex -> eval' $ case args' of
[Record recordData,Int index] -> recordData `listAtIndex` index
RecordSelect -> case args' of
(Record recordData: indexes ) -> Record filteredList
where
indexesRaw = map checkInt indexes
--filteredList = map (eval'.(recordData !!)) indexesRaw
filteredList = map (eval'.listAtIndex recordData) indexesRaw
checkInt (Int i) = i
checkInt _ = error "Arguments to index record 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"
NotEmpty -> case head args' of
(String a) -> Boolean $ (not.null) a
_ -> 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."
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"
Not -> case args' of
[Boolean exp1] -> Boolean $ not exp1
(FuncDef setParams argParams body) -> eval newEnv body
where
newEnv = let (setEnv, argsEnv) = (zip setParams inputSets, zip argParams args) in setEnv ++ argsEnv ++ env
(Var name) -> case findVar env name of
(Just value) -> eval' value
Nothing -> error $ "Variable " ++ name ++ " not found."
(Let _ _ expr) -> expr
(If cond e1 e2) -> eval' $ case eval' cond of
(Boolean True) -> e1
(Boolean False) -> e2
control@(Control lastResult exprs) -> if null exprs then lastResult else
let (newEnv, newControl) = evalControl1 env control in
eval newEnv newControl
(Record exprs) -> Record $ map eval' exprs
(Set exprs) -> Set $ map eval' exprs
_ -> expr
listAtIndex :: [a] -> Int -> a
listAtIndex recordData i | i > length recordData = error $ "Index " ++ show i ++ " too large."
| otherwise = recordData !! (i - 1)
evalControl1 :: Environment -> Expr -> (Environment, Expr)
evalControl1 env (Control last (currentExpr:exprs)) = (newEnv, Control newLast exprs)
where
newLast = eval env $ case currentExpr of
(FuncCall func [] args) -> FuncCall func [last] args
(Let False _ _) -> last
_ -> currentExpr
newEnv = case currentExpr of
(Let _ var expr) -> (var,expr):env
_ -> env
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
concatRecord (Record r1) (Record r2) = Record (r1 ++ r2)
listStartsWith, isSubList :: Eq a => [a] -> [a] -> Bool
listStartsWith = notImplemented -- check if first list starts with second list
isSubList main sub = sub `isInfixOf` main-- check if first list contains second list anywhere in it
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment