csv-parser / src / csvql.hs
csvql.hs
Raw
import System.Environment
import System.IO
import Data.Char

import CSVQLTokens
import CSVQLGrammar
import CSVQLEval
import CSVQLBuiltins
import CSVQLTypes

builtInMap = [("import", importFromCsv),
                ("table", createTable),
                ("add", addRowToTable),
                ("empty", isEmpty), 
                ("length", eLength),
                ("show", printButForReal),
                ("arity", getArity),
                ("max",eMax),
                ("min",eMin)]
builtInTypeMap = [("import", [TypeNull], Iterable TypeTable), 
                ("table", [TypeNull], Iterable TypeTable),
                ("add", [Iterable TypeTable], TypeNull), 
                ("empty", [TypeNull], TypeBool), 
                ("length", [TypeNull], TypeInt),
                ("show", [Iterable TypeTable], TypeNull),
                ("arity", [TypeNull], TypeInt),
                ("max", [TypeNull], TypeBool),
                ("min", [TypeNull], TypeBool)]

main :: IO ()
main = do
    args <- getArgs
    case args of
        [] -> do
            putStrLn "--------------- csvql interpreter version 0.1.7 ---------------"
            interpreter [("out", Iterable TypeTable)] ([("out", Table (Int 0) Null)], Null)
        (filename:_) -> do
            evaluator filename

evaluator :: String -> IO ()
evaluator filename = do
    src <- readFile filename
    let prog = parseCalc (alexScanTokens src)
    (valid, _) <- typesValid prog [("out", Iterable TypeTable)] builtInTypeMap
    if valid
        then do
            (g, _) <- evalExpr builtInMap builtInTypeMap ([("out", Table (Int 0) Null)], prog)
            let out = lookup "out" g
            case out of
                Just table -> do
                    printButForReal (g, table)
                    return ()
                _ -> do
                    hPutStrLn stderr "ERROR: Out table missing"
                    return ()
        else do
            hPutStrLn stderr "ERROR: invalid typing in program, terminating..."
            return ()

interpreter :: VariableTypeMap -> State -> IO ()
interpreter vtm (g, _) = do
    line <- getLine
    case line of
        "exit" -> do
            putStrLn "Exiting interpreter..."
            return ()
        line' -> do
            let prog = parseCalc (alexScanTokens line')
            print prog
            (valid, vtm') <- typesValid prog vtm builtInTypeMap
            if valid
                then do
                    (g', res) <- evalExpr builtInMap builtInTypeMap (g, prog)
                    putStrLn $ "Returned: " ++ show res
                    interpreter vtm' (g', res)
                else do
                    hPutStrLn stderr "ERROR: invalid typing in program, terminating..."
                    return ()