module Language where import qualified Ast as A import Compiler import Lexer (scan) import Parser (parse) import Test.HUnit import Text.Parsec (runParser) import Text.Parsec.Pos (newPos) assertAst :: String -> String -> [A.Expr] -> Assertion assertAst tcase input expected = do r <- return $ runParser (scan parse) () "test" input case r of Left e -> assertFailure $ show e Right ast -> assertEqual tcase ast expected testCase1 = TestCase $ assertAst "parse module" "module main" [A.Module "main" $ newPos "test" 1 1] testCase2 = TestCase $ assertAst "parse a function" "module main\n\ \def fn() { }" [ A.Module "main" $ newPos "test" 1 1, A.Func "fn" [] Nothing [] False False $ newPos "test" 2 1 ] testCase3 = TestCase $ assertAst "parse a function with parameters" "module main\n\ \def fn(a: u8) { }" [ A.Module "main" $ newPos "test" 1 1, A.Func "fn" [("a", A.Type "u8", newPos "test" 2 8)] Nothing [] False False $ newPos "test" 2 1 ] testCase4 = TestCase $ assertAst "parse a function with return value" "module main\n\ \def fn(): u8 {\n\ \return 1; }" [ A.Module "main" $ newPos "test" 1 1, A.Func "fn" [] (Just $ A.Type "u8") [A.Return (Just $ A.Num 1 $ newPos "test" 3 8) $ newPos "test" 3 1] False False $ newPos "test" 2 1 ] testCase5 = TestCase $ assertAst "parse a function call" "module main\n\ \def fn() { }\n\ \fn();" [ A.Module "main" $ newPos "test" 1 1, A.Func "fn" [] Nothing [] False False $ newPos "test" 2 1, A.Call (A.Var "fn" $ newPos "test" 3 1) [] $ newPos "test" 3 1 ] testCase6 = TestCase $ assertAst "parse a function call with arguments" "module main\n\ \def fn(a: u8) { }\n\ \fn(10);" [ A.Module "main" $ newPos "test" 1 1, A.Func "fn" [("a", A.Type "u8", newPos "test" 2 8)] Nothing [] False False $ newPos "test" 2 1, A.Call (A.Var "fn" $ newPos "test" 3 1) [A.Num 10 $ newPos "test" 3 4] $ newPos "test" 3 1 ] testCase7 = TestCase $ assertAst "parse empty return on a function" "module main\n\ \def fn() {\n\ \return; }" [ A.Module "main" $ newPos "test" 1 1, A.Func "fn" [] Nothing [A.Return Nothing $ newPos "test" 3 1] False False $ newPos "test" 2 1 ] language = [testCase1, testCase2, testCase3, testCase4, testCase5, testCase6, testCase7]