From b644978336f3b2455a6067e7892a08de24dc0c22 Mon Sep 17 00:00:00 2001 From: guillaume abel Date: Sat, 2 Dec 2023 19:31:01 +0100 Subject: [PATCH 01/18] Interpreter V.0: Add textToAST parser, handling int64, bool and functions --- app/Main.hs | 5 ++++- src/AST.hs | 20 +++++++++++++++--- src/TextToAST.hs | 53 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 74 insertions(+), 4 deletions(-) diff --git a/app/Main.hs b/app/Main.hs index 8f4b288..0aa55e4 100644 --- a/app/Main.hs +++ b/app/Main.hs @@ -7,5 +7,8 @@ module Main (main) where +import AST (showMaybeTree) +import TextToAST (textToAST) + main :: IO () -main = putStrLn "Hello, World!" +main = putStrLn (showMaybeTree (textToAST "(define tonpereestGAY #t)")) diff --git a/src/AST.hs b/src/AST.hs index a1cf1ff..6b8094b 100644 --- a/src/AST.hs +++ b/src/AST.hs @@ -8,14 +8,28 @@ module AST ( Symbol, - Atom (Number, Symbol), + Atom (Number, Symbol, Boolean), Tree (Node, Leaf), + showMaybeTree ) where import Data.Int (Int64) type Symbol = String -data Atom = Number Int64 | Symbol Symbol +data Atom = Number Int64 | Symbol Symbol | Boolean Bool -data Tree = Node Symbol [Tree] | Leaf Atom +data Tree = Node Symbol (Maybe Tree) (Maybe Tree) | Leaf Atom + +showMaybeTree :: Maybe Tree -> String +showMaybeTree Nothing = "Nothing" +showMaybeTree (Just tree) = show tree + +instance Show Atom where + show (Number value) = "Number : " ++ show value + show (Symbol value) = "Symbol : " ++ value + show (Boolean value) = "Boolean : " ++ show value + +instance Show Tree where + show (Node value left right) = "Node : \"" ++ value ++ "\" left : \"" ++ showMaybeTree left ++ "\" right : \"" ++ showMaybeTree right ++ "\"" + show (Leaf value) = "Leaf : " ++ show value diff --git a/src/TextToAST.hs b/src/TextToAST.hs index 3921b15..8bb0a28 100644 --- a/src/TextToAST.hs +++ b/src/TextToAST.hs @@ -7,4 +7,57 @@ module TextToAST ( + textToAST ) where + +import AST +import Data.Int (Int64) +import Data.Char (isDigit) +import Debug.Trace + +isFunction :: String -> Bool +isFunction [] = False +isFunction (x:_) | x == '(' = True + | otherwise = False + +skipableChar :: Char -> Bool +skipableChar x = x == ' ' || x == '\t' + +notSkipableChar :: Char -> Bool +notSkipableChar x = not (skipableChar x) + +stringIsNumber :: String -> Bool +stringIsNumber [] = False +stringIsNumber (x:[]) | Data.Char.isDigit x = True +stringIsNumber (x:xs) | Data.Char.isDigit x = stringIsNumber xs + | otherwise = False + +nextToParse :: String -> String +nextToParse [] = [] +nextToParse (x:xs) | skipableChar x = nextToParse xs +nextToParse str = dropWhile notSkipableChar str + +createNode :: Symbol -> String -> Maybe Tree +createNode [] _ = Nothing +createNode _ [] = Nothing +createNode (_:xs) str = Just (Node xs (textToAST str) (textToAST (nextToParse str))) + +stringIsBool :: String -> Bool +stringIsBool str = str == "#t" || str == "#f" + +createBool :: String -> Maybe Tree +createBool str | str == "#t" = Just (Leaf (Boolean True)) + | str == "#f" = Just (Leaf (Boolean False)) + | otherwise = Nothing + +treeFromAtom :: String -> String -> Maybe Tree +treeFromAtom [] _ = Nothing +treeFromAtom split _ | stringIsNumber split = Just (Leaf (AST.Number (read split :: Data.Int.Int64))) + | stringIsBool split = createBool split +treeFromAtom split str | isFunction split = createNode split (init str) + | otherwise = Just (Leaf (Symbol split)) + +textToAST :: String -> Maybe Tree +textToAST [] = Nothing +textToAST (x:xs) | skipableChar x = textToAST xs +textToAST str = treeFromAtom (takeWhile notSkipableChar str) (dropWhile notSkipableChar str) From f4ba375b9edad4c5463dcec456a3c1c62ceb2dc5 Mon Sep 17 00:00:00 2001 From: guillaume abel Date: Sat, 2 Dec 2023 20:07:02 +0100 Subject: [PATCH 02/18] Interpreter V.0: Fix remaining debug + wrong word --- app/Main.hs | 2 +- src/TextToAST.hs | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/app/Main.hs b/app/Main.hs index 0aa55e4..cf9f05b 100644 --- a/app/Main.hs +++ b/app/Main.hs @@ -11,4 +11,4 @@ import AST (showMaybeTree) import TextToAST (textToAST) main :: IO () -main = putStrLn (showMaybeTree (textToAST "(define tonpereestGAY #t)")) +main = putStrLn (showMaybeTree (textToAST "(define javascriptIsGood #f)")) diff --git a/src/TextToAST.hs b/src/TextToAST.hs index 8bb0a28..cfd6835 100644 --- a/src/TextToAST.hs +++ b/src/TextToAST.hs @@ -13,7 +13,6 @@ module TextToAST import AST import Data.Int (Int64) import Data.Char (isDigit) -import Debug.Trace isFunction :: String -> Bool isFunction [] = False From fd655e76932b8bd7a1edc475479290599e980592 Mon Sep 17 00:00:00 2001 From: guillaume abel Date: Sat, 2 Dec 2023 20:46:33 +0100 Subject: [PATCH 03/18] Interpreter v.0: Fix pr requests --- src/TextToAST.hs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/TextToAST.hs b/src/TextToAST.hs index cfd6835..504431c 100644 --- a/src/TextToAST.hs +++ b/src/TextToAST.hs @@ -28,6 +28,7 @@ notSkipableChar x = not (skipableChar x) stringIsNumber :: String -> Bool stringIsNumber [] = False stringIsNumber (x:[]) | Data.Char.isDigit x = True + | otherwise = False stringIsNumber (x:xs) | Data.Char.isDigit x = stringIsNumber xs | otherwise = False @@ -45,9 +46,9 @@ stringIsBool :: String -> Bool stringIsBool str = str == "#t" || str == "#f" createBool :: String -> Maybe Tree -createBool str | str == "#t" = Just (Leaf (Boolean True)) - | str == "#f" = Just (Leaf (Boolean False)) - | otherwise = Nothing +createBool "#t" == "#t" = Just (Leaf (Boolean True)) +createBool "#f" = Just (Leaf (Boolean False)) +createBool _ = Nothing treeFromAtom :: String -> String -> Maybe Tree treeFromAtom [] _ = Nothing From 5241cded25c108486107d53b89addf19c002d3ad Mon Sep 17 00:00:00 2001 From: guillaume abel Date: Sat, 2 Dec 2023 20:54:45 +0100 Subject: [PATCH 04/18] Interpreter v.0: Fix compil --- src/TextToAST.hs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/TextToAST.hs b/src/TextToAST.hs index 504431c..2ebb03b 100644 --- a/src/TextToAST.hs +++ b/src/TextToAST.hs @@ -46,7 +46,7 @@ stringIsBool :: String -> Bool stringIsBool str = str == "#t" || str == "#f" createBool :: String -> Maybe Tree -createBool "#t" == "#t" = Just (Leaf (Boolean True)) +createBool "#t" = Just (Leaf (Boolean True)) createBool "#f" = Just (Leaf (Boolean False)) createBool _ = Nothing From 0f82b94bfe1f0fc3f105bfa23aff5238151908b4 Mon Sep 17 00:00:00 2001 From: guillaume abel Date: Sat, 2 Dec 2023 21:26:06 +0100 Subject: [PATCH 05/18] Interpreter v.0: Fix norm --- src/TextToAST.hs | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/src/TextToAST.hs b/src/TextToAST.hs index 2ebb03b..0d8c9f4 100644 --- a/src/TextToAST.hs +++ b/src/TextToAST.hs @@ -16,8 +16,8 @@ import Data.Char (isDigit) isFunction :: String -> Bool isFunction [] = False -isFunction (x:_) | x == '(' = True - | otherwise = False +isFunction ('(':_) = True +isFunction _ = False skipableChar :: Char -> Bool skipableChar x = x == ' ' || x == '\t' @@ -37,10 +37,11 @@ nextToParse [] = [] nextToParse (x:xs) | skipableChar x = nextToParse xs nextToParse str = dropWhile notSkipableChar str -createNode :: Symbol -> String -> Maybe Tree -createNode [] _ = Nothing -createNode _ [] = Nothing -createNode (_:xs) str = Just (Node xs (textToAST str) (textToAST (nextToParse str))) +createNodeFromFunction :: Symbol -> String -> Maybe Tree +createNodeFromFunction [] _ = Nothing +createNodeFromFunction _ [] = Nothing +createNodeFromFunction (_:xs) str = Just (Node xs (textToAST str) + (textToAST (nextToParse str))) stringIsBool :: String -> Bool stringIsBool str = str == "#t" || str == "#f" @@ -52,12 +53,15 @@ createBool _ = Nothing treeFromAtom :: String -> String -> Maybe Tree treeFromAtom [] _ = Nothing -treeFromAtom split _ | stringIsNumber split = Just (Leaf (AST.Number (read split :: Data.Int.Int64))) +treeFromAtom split _ | stringIsNumber split = + Just (Leaf (AST.Number (read split :: Data.Int.Int64))) | stringIsBool split = createBool split -treeFromAtom split str | isFunction split = createNode split (init str) +treeFromAtom split str | isFunction split = + createNodeFromFunction split (init str) | otherwise = Just (Leaf (Symbol split)) textToAST :: String -> Maybe Tree textToAST [] = Nothing textToAST (x:xs) | skipableChar x = textToAST xs -textToAST str = treeFromAtom (takeWhile notSkipableChar str) (dropWhile notSkipableChar str) +textToAST str = treeFromAtom (takeWhile notSkipableChar str) + (dropWhile notSkipableChar str) From f9c87b54f690079589859d3cc7ab1834f2a875a8 Mon Sep 17 00:00:00 2001 From: Xavier Mitault Date: Sat, 2 Dec 2023 21:06:18 +0000 Subject: [PATCH 06/18] Fix test maybe PATCH --- test/Spec.hs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/test/Spec.hs b/test/Spec.hs index d7ca972..0d7f9af 100644 --- a/test/Spec.hs +++ b/test/Spec.hs @@ -13,9 +13,13 @@ tests = testGroup "Tests" [unitTests] unitTests :: TestTree unitTests = testGroup "Unit tests" [ testCase "Basic AST creation 0" $ - assertEqual "define x 42" (Node "define" [Leaf (Symbol "x"), Leaf (Number 42)]) (Node "define" [Leaf (Symbol "x"), Leaf (Number 42)]) + assertEqual "define x 42" (Node "define" (Just $ Leaf (Symbol "x")) (Just $ Leaf (Number 42))) (Node "define" (Just $ Leaf (Symbol "x")) (Just $ Leaf (Number 42))) , testCase "Basic AST creation 1" $ assertEqual "foo" (Leaf (Symbol "foo")) (Leaf (Symbol "foo")) , testCase "Basic AST creation 2" $ assertEqual "42" (Leaf (Number 42)) (Leaf (Number 42)) + , testCase "Basic AST creation 3" $ + assertEqual "#f" (Leaf (Boolean False)) (Leaf (Boolean False)) + , testCase "Basic AST creation 4" $ + assertEqual "#t" (Leaf (Boolean True)) (Leaf (Boolean True)) ] From 3d3a59113ce7f17bc88136ee806c7a2ba624e058 Mon Sep 17 00:00:00 2001 From: Xavier Mitault Date: Mon, 4 Dec 2023 10:01:03 +0000 Subject: [PATCH 07/18] Add test for Varidadic argument/list MINOR --- test/Spec.hs | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/test/Spec.hs b/test/Spec.hs index 0d7f9af..7b4d2e6 100644 --- a/test/Spec.hs +++ b/test/Spec.hs @@ -3,15 +3,16 @@ import Test.Tasty.HUnit import Test.Tasty.Runners.Html import AST +import TextToAST main :: IO () main = defaultMainWithIngredients (htmlRunner : defaultIngredients) tests tests :: TestTree -tests = testGroup "Tests" [unitTests] +tests = testGroup "Tests" [unitTestsASTEqual, unitTestsASTParse] -unitTests :: TestTree -unitTests = testGroup "Unit tests" +unitTestsASTEqual :: TestTree +unitTestsASTEqual = testGroup "AST Equal Tests" [ testCase "Basic AST creation 0" $ assertEqual "define x 42" (Node "define" (Just $ Leaf (Symbol "x")) (Just $ Leaf (Number 42))) (Node "define" (Just $ Leaf (Symbol "x")) (Just $ Leaf (Number 42))) , testCase "Basic AST creation 1" $ @@ -23,3 +24,9 @@ unitTests = testGroup "Unit tests" , testCase "Basic AST creation 4" $ assertEqual "#t" (Leaf (Boolean True)) (Leaf (Boolean True)) ] + +unitTestsASTParse :: TestTree +unitTestsASTParse = testGroup "AST Parse Tests" + [ testCase "Basic AST creation 0" $ + assertEqual (textToAST "(foo abc def hij)") (Just $ (Node "foo" (Leaf (Symbol "abc"))) (Varidadic (Leaf (Symbol "def") (Leaf (Symbol "hij"))))) + ] From 0fd772981d9e9dce50899642ac240553cffc3013 Mon Sep 17 00:00:00 2001 From: Xavier Mitault Date: Mon, 4 Dec 2023 11:15:33 +0000 Subject: [PATCH 08/18] Send bad exit code if error --- .github/workflows/tests.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index b89f8ee..dd66015 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -86,3 +86,9 @@ jobs: tests.log refresh-message-position: true message-id: tests-cicd + + - name: Exit Status + run: | + if [ ${{ steps.failedTest.outputs.failedTest }} == 'true' ]; then + exit 1 + fi From 47ff922b231776ff6453240fe72d7462e11215c0 Mon Sep 17 00:00:00 2001 From: guillaume abel Date: Mon, 4 Dec 2023 16:02:14 +0100 Subject: [PATCH 09/18] Interpreter v.0: Add current progress --- app/Main.hs | 2 +- src/AST.hs | 6 ++++-- src/TextToAST.hs | 38 ++++++++++++++++++++++++++------------ 3 files changed, 31 insertions(+), 15 deletions(-) diff --git a/app/Main.hs b/app/Main.hs index b450fa0..abc153c 100644 --- a/app/Main.hs +++ b/app/Main.hs @@ -11,4 +11,4 @@ import AST (showMaybeTree) import TextToAST (textToAST) main :: IO () -main = putStrLn (showMaybeTree (textToAST "(define javascriptIsGood #f)")) +main = putStrLn (showMaybeTree (textToAST "(define javascriptIsGood #f 42)")) diff --git a/src/AST.hs b/src/AST.hs index 6f28f89..3f3ea94 100644 --- a/src/AST.hs +++ b/src/AST.hs @@ -9,7 +9,7 @@ module AST ( Symbol, Atom (Number, Symbol, Boolean), - Tree (Node, Leaf), + Tree (Node, Leaf, Variadic) showMaybeTree ) where @@ -19,7 +19,7 @@ type Symbol = String data Atom = Number Int64 | Symbol Symbol | Boolean Bool -data Tree = Node Symbol (Maybe Tree) (Maybe Tree) | Leaf Atom +data Tree = Node Symbol (Maybe Tree) (Maybe Tree) | Leaf Atom | Variadic (Maybe Tree) (Maybe Tree) showMaybeTree :: Maybe Tree -> String showMaybeTree Nothing = "Nothing" @@ -39,8 +39,10 @@ instance Show Atom where instance Eq Tree where Node a fst_ scd == Node b bfst bscd = a == b && fst_ == bfst && scd == bscd Leaf a == Leaf b = a == b + Variadic fst_ scd == Variadic bfst bscd = fst_ == bfst && scd == bscd _ == _ = False instance Show Tree where show (Node value fst_ scd) = "Node:'" ++ value ++ "' first: '{" ++ showMaybeTree fst_ ++ "} second: {" ++ showMaybeTree scd ++ "}'" show (Leaf value) = "Leaf:'" ++ show value ++ "'" + show (Variadic fst_ scd) = "Variadic first: {" ++ showMaybeTree fst_ ++ "} second: {" ++ showMaybeTree scd ++ "}" diff --git a/src/TextToAST.hs b/src/TextToAST.hs index 04c0511..7052361 100644 --- a/src/TextToAST.hs +++ b/src/TextToAST.hs @@ -20,7 +20,9 @@ isFunction ('(':_) = True isFunction _ = False skipableChar :: Char -> Bool -skipableChar x = x == ' ' || x == '\t' +skipableChar ' ' = True +skipableChar '\t' = True +skipableChar _ = False notSkipableChar :: Char -> Bool notSkipableChar x = not (skipableChar x) @@ -34,17 +36,30 @@ stringIsNumber (x:xs) | Data.Char.isDigit x = stringIsNumber xs nextToParse :: String -> String nextToParse [] = [] -nextToParse (x:xs) | skipableChar x = nextToParse xs -nextToParse str = dropWhile notSkipableChar str +nextToParse ('(':xs) +nextToParse str = dropWhile skipableChar (dropWhile notSkipableChar (dropWhile skipableChar (x:xs)) -createNodeFromFunction :: Symbol -> String -> Maybe Tree -createNodeFromFunction [] _ = Nothing -createNodeFromFunction _ [] = Nothing -createNodeFromFunction (_:xs) str = Just (Node xs (textToAST str) - (textToAST (nextToParse str))) +countAtoms :: String -> Int -> Int +countAtoms str depth | depth >= 2 = 2 + | len str > 0 = countAtoms (nextToParse str) (depth + 1) + | otherwise = depth + +createVariadic :: String -> Variadic +createVariadic str = Variadic (textToAST str) (textToAST (nextToParse str)) + +createNodeFromFunction :: Symbol -> String -> Int -> Maybe Tree +createNodeFromFunction [] _ _ = Nothing +createNodeFromFunction _ [] _ = Nothing +createNodeFromFunction (_:xs) str 0 = Just (Node xs Nothing Nothing) +createNodeFromFunction (_:xs) str 1 = Just (Node xs (textToAST str) + (checkNextToParse textToAST (nextToParse str))) +createNodeFromFunction (_:xs) str 2 = + Just (Node xs (textToAST str) (createVariadic (nextToparse str))) stringIsBool :: String -> Bool -stringIsBool str = str == "#t" || str == "#f" +stringIsBool "#t" = True +stringIsBool "#f" = True +stringIsBool _ = False createBool :: String -> Maybe Tree createBool "#t" = Just (Leaf (Boolean True)) @@ -57,11 +72,10 @@ treeFromAtom split _ | stringIsNumber split = Just (Leaf (AST.Number (read split :: Data.Int.Int64))) | stringIsBool split = createBool split treeFromAtom split str | isFunction split = - createNodeFromFunction split (init str) + createNodeFromFunction split str (countAtoms (nextToParse str) 0) | otherwise = Just (Leaf (Symbol split)) textToAST :: String -> Maybe Tree textToAST [] = Nothing textToAST (x:xs) | skipableChar x = textToAST xs -textToAST str = treeFromAtom (takeWhile notSkipableChar str) - (dropWhile notSkipableChar str) + | otherwise = treeFromAtom (takeWhile notSkipableChar (x:xs)) (dropWhile notSkipableChar (x:xs)) From c21ab8fcc794e52b6bf735f333dc49c56be20f05 Mon Sep 17 00:00:00 2001 From: Xavier Mitault Date: Mon, 4 Dec 2023 16:01:33 +0000 Subject: [PATCH 10/18] Remove some compil error PATCH --- src/AST.hs | 2 +- src/TextToAST.hs | 17 +++++++++-------- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/src/AST.hs b/src/AST.hs index 3f3ea94..bf7a104 100644 --- a/src/AST.hs +++ b/src/AST.hs @@ -9,7 +9,7 @@ module AST ( Symbol, Atom (Number, Symbol, Boolean), - Tree (Node, Leaf, Variadic) + Tree (Node, Leaf, Variadic), showMaybeTree ) where diff --git a/src/TextToAST.hs b/src/TextToAST.hs index 7052361..99d11e2 100644 --- a/src/TextToAST.hs +++ b/src/TextToAST.hs @@ -29,32 +29,33 @@ notSkipableChar x = not (skipableChar x) stringIsNumber :: String -> Bool stringIsNumber [] = False -stringIsNumber (x:[]) | Data.Char.isDigit x = True +stringIsNumber [x] | Data.Char.isDigit x = True | otherwise = False stringIsNumber (x:xs) | Data.Char.isDigit x = stringIsNumber xs | otherwise = False nextToParse :: String -> String nextToParse [] = [] -nextToParse ('(':xs) -nextToParse str = dropWhile skipableChar (dropWhile notSkipableChar (dropWhile skipableChar (x:xs)) +nextToParse ('(':xs) = xs +nextToParse str = dropWhile skipableChar (dropWhile notSkipableChar (dropWhile skipableChar str)) countAtoms :: String -> Int -> Int countAtoms str depth | depth >= 2 = 2 - | len str > 0 = countAtoms (nextToParse str) (depth + 1) + | not (null str) = countAtoms (nextToParse str) (depth + 1) | otherwise = depth -createVariadic :: String -> Variadic -createVariadic str = Variadic (textToAST str) (textToAST (nextToParse str)) +createVariadic :: String -> Maybe Tree +createVariadic str = Just $ Variadic (textToAST str) (textToAST (nextToParse str)) createNodeFromFunction :: Symbol -> String -> Int -> Maybe Tree createNodeFromFunction [] _ _ = Nothing createNodeFromFunction _ [] _ = Nothing -createNodeFromFunction (_:xs) str 0 = Just (Node xs Nothing Nothing) +createNodeFromFunction (_:xs) _ 0 = Just (Node xs Nothing Nothing) createNodeFromFunction (_:xs) str 1 = Just (Node xs (textToAST str) (checkNextToParse textToAST (nextToParse str))) createNodeFromFunction (_:xs) str 2 = - Just (Node xs (textToAST str) (createVariadic (nextToparse str))) + Just (Node xs (textToAST str) (createVariadic (nextToParse str))) +createNodeFromFunction _ _ _ = Nothing stringIsBool :: String -> Bool stringIsBool "#t" = True From d2414a3f8546fe512f7b3b6cfec56329a5a145df Mon Sep 17 00:00:00 2001 From: Xavier Mitault Date: Mon, 4 Dec 2023 17:50:21 +0000 Subject: [PATCH 11/18] Fix last part of variadic MINOR --- .gitignore | 2 +- src/TextToAST.hs | 13 ++++++++++--- test/Spec.hs | 2 +- 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/.gitignore b/.gitignore index 826e993..b1e48a8 100644 --- a/.gitignore +++ b/.gitignore @@ -166,7 +166,7 @@ tags .idea/* -/koaky +/koaky-exe /glados *.log diff --git a/src/TextToAST.hs b/src/TextToAST.hs index 99d11e2..811dc3b 100644 --- a/src/TextToAST.hs +++ b/src/TextToAST.hs @@ -34,9 +34,16 @@ stringIsNumber [x] | Data.Char.isDigit x = True stringIsNumber (x:xs) | Data.Char.isDigit x = stringIsNumber xs | otherwise = False +nextToParse' :: String -> Int -> String +nextToParse' [] _ = [] +nextToParse' (')':xs) 1 = dropWhile skipableChar xs +nextToParse' (')':xs) depth = nextToParse' xs (depth - 1) +nextToParse' ('(':xs) depth = nextToParse' xs (depth + 1) +nextToParse' (_:xs) depth = nextToParse' xs depth + nextToParse :: String -> String nextToParse [] = [] -nextToParse ('(':xs) = xs +nextToParse ('(':xs) = nextToParse' xs 0 nextToParse str = dropWhile skipableChar (dropWhile notSkipableChar (dropWhile skipableChar str)) countAtoms :: String -> Int -> Int @@ -52,7 +59,7 @@ createNodeFromFunction [] _ _ = Nothing createNodeFromFunction _ [] _ = Nothing createNodeFromFunction (_:xs) _ 0 = Just (Node xs Nothing Nothing) createNodeFromFunction (_:xs) str 1 = Just (Node xs (textToAST str) - (checkNextToParse textToAST (nextToParse str))) + (textToAST (nextToParse str))) createNodeFromFunction (_:xs) str 2 = Just (Node xs (textToAST str) (createVariadic (nextToParse str))) createNodeFromFunction _ _ _ = Nothing @@ -74,7 +81,7 @@ treeFromAtom split _ | stringIsNumber split = | stringIsBool split = createBool split treeFromAtom split str | isFunction split = createNodeFromFunction split str (countAtoms (nextToParse str) 0) - | otherwise = Just (Leaf (Symbol split)) + | otherwise = Just (Leaf (Symbol $ takeWhile (/= ')') split)) textToAST :: String -> Maybe Tree textToAST [] = Nothing diff --git a/test/Spec.hs b/test/Spec.hs index 7b4d2e6..ccee9aa 100644 --- a/test/Spec.hs +++ b/test/Spec.hs @@ -28,5 +28,5 @@ unitTestsASTEqual = testGroup "AST Equal Tests" unitTestsASTParse :: TestTree unitTestsASTParse = testGroup "AST Parse Tests" [ testCase "Basic AST creation 0" $ - assertEqual (textToAST "(foo abc def hij)") (Just $ (Node "foo" (Leaf (Symbol "abc"))) (Varidadic (Leaf (Symbol "def") (Leaf (Symbol "hij"))))) + assertEqual "(foo abc def hij)" (textToAST "(foo abc def hij)") (Just $ (Node "foo" (Just $ Leaf (Symbol "abc"))) (Just $ Variadic (Just $ Leaf (Symbol "def")) (Just $ Leaf (Symbol "hij")))) ] From 8afc1f925bbf113ef46f57190377f703af27a119 Mon Sep 17 00:00:00 2001 From: Xavier Mitault Date: Mon, 4 Dec 2023 18:37:06 +0000 Subject: [PATCH 12/18] Add test for some parsing case MINOR --- src/TextToAST.hs | 22 ++++++++----- test/Spec.hs | 83 ++++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 90 insertions(+), 15 deletions(-) diff --git a/src/TextToAST.hs b/src/TextToAST.hs index 811dc3b..4268916 100644 --- a/src/TextToAST.hs +++ b/src/TextToAST.hs @@ -30,9 +30,15 @@ notSkipableChar x = not (skipableChar x) stringIsNumber :: String -> Bool stringIsNumber [] = False stringIsNumber [x] | Data.Char.isDigit x = True - | otherwise = False -stringIsNumber (x:xs) | Data.Char.isDigit x = stringIsNumber xs - | otherwise = False + | otherwise = False +stringIsNumber (x:xs:xss) | Data.Char.isDigit x && xs == ')' = + stringIsNumber (xs:xss) + | Data.Char.isDigit x = True + | skipableChar x = stringIsNumber (xs:xss) + | otherwise = False + +parseStringNumber :: String -> Atom +parseStringNumber str = Number (read (takeWhile (\x -> notSkipableChar x && x /= ')') str) :: Data.Int.Int64) nextToParse' :: String -> Int -> String nextToParse' [] _ = [] @@ -76,11 +82,11 @@ createBool _ = Nothing treeFromAtom :: String -> String -> Maybe Tree treeFromAtom [] _ = Nothing -treeFromAtom split _ | stringIsNumber split = - Just (Leaf (AST.Number (read split :: Data.Int.Int64))) - | stringIsBool split = createBool split -treeFromAtom split str | isFunction split = - createNodeFromFunction split str (countAtoms (nextToParse str) 0) +treeFromAtom split str | stringIsNumber split = + Just (Leaf (parseStringNumber split)) + | stringIsBool split = createBool split + | isFunction split = + createNodeFromFunction split str (countAtoms (nextToParse str) 0) | otherwise = Just (Leaf (Symbol $ takeWhile (/= ')') split)) textToAST :: String -> Maybe Tree diff --git a/test/Spec.hs b/test/Spec.hs index ccee9aa..6343772 100644 --- a/test/Spec.hs +++ b/test/Spec.hs @@ -14,19 +14,88 @@ tests = testGroup "Tests" [unitTestsASTEqual, unitTestsASTParse] unitTestsASTEqual :: TestTree unitTestsASTEqual = testGroup "AST Equal Tests" [ testCase "Basic AST creation 0" $ - assertEqual "define x 42" (Node "define" (Just $ Leaf (Symbol "x")) (Just $ Leaf (Number 42))) (Node "define" (Just $ Leaf (Symbol "x")) (Just $ Leaf (Number 42))) + assertEqual "define x 42" + (Node "define" (Just $ Leaf (Symbol "x")) (Just $ Leaf (Number 42))) + (Node "define" (Just $ Leaf (Symbol "x")) (Just $ Leaf (Number 42))) , testCase "Basic AST creation 1" $ - assertEqual "foo" (Leaf (Symbol "foo")) (Leaf (Symbol "foo")) + assertEqual "foo" + (Leaf (Symbol "foo")) + (Leaf (Symbol "foo")) , testCase "Basic AST creation 2" $ - assertEqual "42" (Leaf (Number 42)) (Leaf (Number 42)) + assertEqual "42" + (Leaf (Number 42)) + (Leaf (Number 42)) , testCase "Basic AST creation 3" $ - assertEqual "#f" (Leaf (Boolean False)) (Leaf (Boolean False)) + assertEqual "#f" + (Leaf (Boolean False)) + (Leaf (Boolean False)) , testCase "Basic AST creation 4" $ - assertEqual "#t" (Leaf (Boolean True)) (Leaf (Boolean True)) + assertEqual "#t" + (Leaf (Boolean True)) + (Leaf (Boolean True)) ] unitTestsASTParse :: TestTree unitTestsASTParse = testGroup "AST Parse Tests" - [ testCase "Basic AST creation 0" $ - assertEqual "(foo abc def hij)" (textToAST "(foo abc def hij)") (Just $ (Node "foo" (Just $ Leaf (Symbol "abc"))) (Just $ Variadic (Just $ Leaf (Symbol "def")) (Just $ Leaf (Symbol "hij")))) + [ testCase "(foo abc def hij)" $ + assertEqual "(foo abc def hij)" + (Just $ Node "foo" + (Just $ Leaf (Symbol "abc")) + (Just $ Variadic + (Just $ Leaf (Symbol "def")) + (Just $ Leaf (Symbol "hij")) + ) + ) + (textToAST "(foo abc def hij)") + , testCase "(define x 42)" $ + assertEqual "(define x 42)" + (Just $ Node "define" + (Just $ Leaf (Symbol "x")) + (Just $ Leaf (Number 42)) + ) + (textToAST "(define x 42)") + , testCase "42" $ + assertEqual "42" + (Just $ Leaf (Number 42)) + (textToAST "42") + , testCase "#f" $ + assertEqual "#f" + (Just $ Leaf (Boolean False)) + (textToAST "#f") + , testCase "#t" $ + assertEqual "#t" + (Just $ Leaf (Boolean True)) + (textToAST "#t") + , testCase "foo" $ + assertEqual "foo" + (Just $ Leaf (Symbol "foo")) + (textToAST "foo") + , testCase "(foo)" $ + assertEqual "(foo)" + (Just $ Node "foo" Nothing Nothing) + (textToAST "(foo)") + , testCase "(foo def)" $ + assertEqual "(foo def)" + (Just $ Node "foo" + (Just $ Leaf (Symbol "def")) + Nothing + ) + (textToAST "(foo def)") + , testCase "(foo def #t)" $ + assertEqual "(foo def #t)" + (Just $ Node "foo" + (Just $ Leaf (Symbol "def")) + (Just $ Leaf (Boolean True)) + ) + (textToAST "(foo def #t)") + , testCase "(foo def #t #f)" $ + assertEqual "(foo def #t #f)" + (Just $ Node "foo" + (Just $ Leaf (Symbol "def")) + (Just $ Variadic + (Just $ Leaf (Boolean True)) + (Just $ Leaf (Boolean False)) + ) + ) + (textToAST "(foo def #t #f)") ] From 91c86ef32e8297e2ab9766faab0a5ffb133cfedc Mon Sep 17 00:00:00 2001 From: Xavier Mitault Date: Mon, 4 Dec 2023 19:12:07 +0000 Subject: [PATCH 13/18] Add more tests and Fix bug MINOR --- src/TextToAST.hs | 19 ++++++++++++++++--- test/Spec.hs | 24 ++++++++++++++++++++++++ 2 files changed, 40 insertions(+), 3 deletions(-) diff --git a/src/TextToAST.hs b/src/TextToAST.hs index 4268916..bd8845f 100644 --- a/src/TextToAST.hs +++ b/src/TextToAST.hs @@ -62,8 +62,9 @@ createVariadic str = Just $ Variadic (textToAST str) (textToAST (nextToParse str createNodeFromFunction :: Symbol -> String -> Int -> Maybe Tree createNodeFromFunction [] _ _ = Nothing +createNodeFromFunction (_:xs) [] 0 = Just (Node xs Nothing Nothing) +createNodeFromFunction (_:xs) str 0 = Just (Node xs (textToAST str) Nothing) createNodeFromFunction _ [] _ = Nothing -createNodeFromFunction (_:xs) _ 0 = Just (Node xs Nothing Nothing) createNodeFromFunction (_:xs) str 1 = Just (Node xs (textToAST str) (textToAST (nextToParse str))) createNodeFromFunction (_:xs) str 2 = @@ -73,11 +74,21 @@ createNodeFromFunction _ _ _ = Nothing stringIsBool :: String -> Bool stringIsBool "#t" = True stringIsBool "#f" = True +stringIsBool ('#':'t':xs) | xs == ")" = True + | dropWhile skipableChar xs == ")" = True +stringIsBool ('#':'f':xs) | xs == ")" = True + | dropWhile skipableChar xs == ")" = True stringIsBool _ = False createBool :: String -> Maybe Tree createBool "#t" = Just (Leaf (Boolean True)) +createBool ('#':'t':xs) | xs == ")" = Just (Leaf (Boolean True)) + | dropWhile skipableChar xs == ")" = + Just (Leaf (Boolean True)) createBool "#f" = Just (Leaf (Boolean False)) +createBool ('#':'f':xs) | xs == ")" = Just (Leaf (Boolean False)) + | dropWhile skipableChar xs == ")" = + Just (Leaf (Boolean False)) createBool _ = Nothing treeFromAtom :: String -> String -> Maybe Tree @@ -85,8 +96,10 @@ treeFromAtom [] _ = Nothing treeFromAtom split str | stringIsNumber split = Just (Leaf (parseStringNumber split)) | stringIsBool split = createBool split - | isFunction split = - createNodeFromFunction split str (countAtoms (nextToParse str) 0) + | isFunction split = createNodeFromFunction + (takeWhile (/= ')') split) + str + (countAtoms (nextToParse str) 0) | otherwise = Just (Leaf (Symbol $ takeWhile (/= ')') split)) textToAST :: String -> Maybe Tree diff --git a/test/Spec.hs b/test/Spec.hs index 6343772..9e85b33 100644 --- a/test/Spec.hs +++ b/test/Spec.hs @@ -88,6 +88,20 @@ unitTestsASTParse = testGroup "AST Parse Tests" (Just $ Leaf (Boolean True)) ) (textToAST "(foo def #t)") + , testCase "(foo def #f)" $ + assertEqual "(foo def #f)" + (Just $ Node "foo" + (Just $ Leaf (Symbol "def")) + (Just $ Leaf (Boolean False)) + ) + (textToAST "(foo def #f)") + , testCase "(foo #f def)" $ + assertEqual "(foo #f def)" + (Just $ Node "foo" + (Just $ Leaf (Boolean False)) + (Just $ Leaf (Symbol "def")) + ) + (textToAST "(foo #f def)") , testCase "(foo def #t #f)" $ assertEqual "(foo def #t #f)" (Just $ Node "foo" @@ -98,4 +112,14 @@ unitTestsASTParse = testGroup "AST Parse Tests" ) ) (textToAST "(foo def #t #f)") + , testCase "(foo def #f #t)" $ + assertEqual "(foo def #f #t)" + (Just $ Node "foo" + (Just $ Leaf (Symbol "def")) + (Just $ Variadic + (Just $ Leaf (Boolean False)) + (Just $ Leaf (Boolean True)) + ) + ) + (textToAST "(foo def #f #t)") ] From 7d16bd98f5dbad2d4bc69b4dcd79a9779fe10fe0 Mon Sep 17 00:00:00 2001 From: guillaume abel Date: Mon, 4 Dec 2023 20:39:22 +0100 Subject: [PATCH 14/18] Interpreter v.0: Add test --- test/Spec.hs | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/test/Spec.hs b/test/Spec.hs index 9e85b33..b7225fe 100644 --- a/test/Spec.hs +++ b/test/Spec.hs @@ -122,4 +122,17 @@ unitTestsASTParse = testGroup "AST Parse Tests" ) ) (textToAST "(foo def #f #t)") + , testCase "(fst 1 (scd 2 3 4))" $ + assertEqual "(fst 1 (scd 2 3 4))" + (Just $ Node "fst" + (Just $ Leaf (Number 1)) + (Just $ Node "scd" + (Just $ Leaf (Number 2)) + (Just $ Variadic + (Just $ Leaf (Number 3)) + (Just $ Leaf (Number 4)) + ) + ) + ) + (textToAST "(fst 1 (scd 2 3 4))") ] From 9ab54bf03ca54aa152494a1790a4da5f0fb18308 Mon Sep 17 00:00:00 2001 From: Xavier Mitault Date: Mon, 4 Dec 2023 19:45:38 +0000 Subject: [PATCH 15/18] Add test and bug fix MINOR --- src/TextToAST.hs | 17 ++++++++++------- test/Spec.hs | 14 ++++++++++++++ 2 files changed, 24 insertions(+), 7 deletions(-) diff --git a/src/TextToAST.hs b/src/TextToAST.hs index bd8845f..4f5fdc7 100644 --- a/src/TextToAST.hs +++ b/src/TextToAST.hs @@ -27,22 +27,25 @@ skipableChar _ = False notSkipableChar :: Char -> Bool notSkipableChar x = not (skipableChar x) +stringIsNumber' :: String -> Bool +stringIsNumber' [] = False +stringIsNumber' [x] | Data.Char.isDigit x = True + | otherwise = False +stringIsNumber' (x:xs) | Data.Char.isDigit x = stringIsNumber' xs + | otherwise = False + stringIsNumber :: String -> Bool stringIsNumber [] = False stringIsNumber [x] | Data.Char.isDigit x = True | otherwise = False -stringIsNumber (x:xs:xss) | Data.Char.isDigit x && xs == ')' = - stringIsNumber (xs:xss) - | Data.Char.isDigit x = True - | skipableChar x = stringIsNumber (xs:xss) - | otherwise = False +stringIsNumber str = stringIsNumber' (takeWhile (\x -> notSkipableChar x && x /= ')') str) parseStringNumber :: String -> Atom parseStringNumber str = Number (read (takeWhile (\x -> notSkipableChar x && x /= ')') str) :: Data.Int.Int64) nextToParse' :: String -> Int -> String nextToParse' [] _ = [] -nextToParse' (')':xs) 1 = dropWhile skipableChar xs +nextToParse' (')':xs) 1 = dropWhile (\x -> skipableChar x || x == ')') xs nextToParse' (')':xs) depth = nextToParse' xs (depth - 1) nextToParse' ('(':xs) depth = nextToParse' xs (depth + 1) nextToParse' (_:xs) depth = nextToParse' xs depth @@ -54,7 +57,7 @@ nextToParse str = dropWhile skipableChar (dropWhile notSkipableChar (dropWhile s countAtoms :: String -> Int -> Int countAtoms str depth | depth >= 2 = 2 - | not (null str) = countAtoms (nextToParse str) (depth + 1) + | not (null $ dropWhile skipableChar str) = countAtoms (nextToParse str) (depth + 1) | otherwise = depth createVariadic :: String -> Maybe Tree diff --git a/test/Spec.hs b/test/Spec.hs index b7225fe..48a0fce 100644 --- a/test/Spec.hs +++ b/test/Spec.hs @@ -135,4 +135,18 @@ unitTestsASTParse = testGroup "AST Parse Tests" ) ) (textToAST "(fst 1 (scd 2 3 4))") + , testCase "(foo 42 )" $ + assertEqual "(foo 42 )" + (Just $ Node "foo" + (Just $ Leaf (Number 42)) + Nothing + ) + (textToAST "(foo 42 )") + , testCase "(foo def )" $ + assertEqual "(foo 42 )" + (Just $ Node "foo" + (Just $ Leaf (Symbol "def")) + Nothing + ) + (textToAST "(foo def )") ] From a9453c7bf2a9783c61160196fb0ed4ae39f3629d Mon Sep 17 00:00:00 2001 From: Xavier Mitault Date: Mon, 4 Dec 2023 19:56:22 +0000 Subject: [PATCH 16/18] Fix bug space at end PATCH --- src/TextToAST.hs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/TextToAST.hs b/src/TextToAST.hs index 4f5fdc7..433e4ce 100644 --- a/src/TextToAST.hs +++ b/src/TextToAST.hs @@ -57,7 +57,7 @@ nextToParse str = dropWhile skipableChar (dropWhile notSkipableChar (dropWhile s countAtoms :: String -> Int -> Int countAtoms str depth | depth >= 2 = 2 - | not (null $ dropWhile skipableChar str) = countAtoms (nextToParse str) (depth + 1) + | not (null $ takeWhile (/= ')') (dropWhile skipableChar str)) = countAtoms (nextToParse str) (depth + 1) | otherwise = depth createVariadic :: String -> Maybe Tree From f5d5eb79002d472e9c7fec0b94c221f122880092 Mon Sep 17 00:00:00 2001 From: Xavier Mitault Date: Mon, 4 Dec 2023 20:00:43 +0000 Subject: [PATCH 17/18] Fix line too long PATCH --- src/TextToAST.hs | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/src/TextToAST.hs b/src/TextToAST.hs index 433e4ce..b93f94f 100644 --- a/src/TextToAST.hs +++ b/src/TextToAST.hs @@ -38,10 +38,14 @@ stringIsNumber :: String -> Bool stringIsNumber [] = False stringIsNumber [x] | Data.Char.isDigit x = True | otherwise = False -stringIsNumber str = stringIsNumber' (takeWhile (\x -> notSkipableChar x && x /= ')') str) +stringIsNumber str = + stringIsNumber' (takeWhile (\x -> notSkipableChar x && x /= ')') str) parseStringNumber :: String -> Atom -parseStringNumber str = Number (read (takeWhile (\x -> notSkipableChar x && x /= ')') str) :: Data.Int.Int64) +parseStringNumber str = + Number (read + (takeWhile (\x -> notSkipableChar x && x /= ')') str) + :: Data.Int.Int64) nextToParse' :: String -> Int -> String nextToParse' [] _ = [] @@ -53,15 +57,20 @@ nextToParse' (_:xs) depth = nextToParse' xs depth nextToParse :: String -> String nextToParse [] = [] nextToParse ('(':xs) = nextToParse' xs 0 -nextToParse str = dropWhile skipableChar (dropWhile notSkipableChar (dropWhile skipableChar str)) +nextToParse str = dropWhile skipableChar + (dropWhile notSkipableChar (dropWhile skipableChar str)) countAtoms :: String -> Int -> Int countAtoms str depth | depth >= 2 = 2 - | not (null $ takeWhile (/= ')') (dropWhile skipableChar str)) = countAtoms (nextToParse str) (depth + 1) + | not (null $ takeWhile + (/= ')') + (dropWhile skipableChar str)) = + countAtoms (nextToParse str) (depth + 1) | otherwise = depth createVariadic :: String -> Maybe Tree -createVariadic str = Just $ Variadic (textToAST str) (textToAST (nextToParse str)) +createVariadic str = + Just $ Variadic (textToAST str) (textToAST (nextToParse str)) createNodeFromFunction :: Symbol -> String -> Int -> Maybe Tree createNodeFromFunction [] _ _ = Nothing @@ -103,9 +112,13 @@ treeFromAtom split str | stringIsNumber split = (takeWhile (/= ')') split) str (countAtoms (nextToParse str) 0) - | otherwise = Just (Leaf (Symbol $ takeWhile (/= ')') split)) + | otherwise = + Just (Leaf (Symbol $ takeWhile (/= ')') split)) textToAST :: String -> Maybe Tree textToAST [] = Nothing textToAST (x:xs) | skipableChar x = textToAST xs - | otherwise = treeFromAtom (takeWhile notSkipableChar (x:xs)) (dropWhile notSkipableChar (x:xs)) + | otherwise = + treeFromAtom + (takeWhile notSkipableChar (x:xs)) + (dropWhile notSkipableChar (x:xs)) From c81bc175958cd2326072f696d39d75f4357bd517 Mon Sep 17 00:00:00 2001 From: Xavier Mitault Date: Mon, 4 Dec 2023 20:06:06 +0000 Subject: [PATCH 18/18] Fix norm guard PATCH --- src/TextToAST.hs | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/src/TextToAST.hs b/src/TextToAST.hs index b93f94f..107b602 100644 --- a/src/TextToAST.hs +++ b/src/TextToAST.hs @@ -86,21 +86,25 @@ createNodeFromFunction _ _ _ = Nothing stringIsBool :: String -> Bool stringIsBool "#t" = True stringIsBool "#f" = True -stringIsBool ('#':'t':xs) | xs == ")" = True - | dropWhile skipableChar xs == ")" = True -stringIsBool ('#':'f':xs) | xs == ")" = True - | dropWhile skipableChar xs == ")" = True +stringIsBool "#f)" = True +stringIsBool "#t)" = True +stringIsBool ('#':'t':xs) | dropWhile skipableChar xs == ")" = True + | otherwise = False +stringIsBool ('#':'f':xs) | dropWhile skipableChar xs == ")" = True + | otherwise = False stringIsBool _ = False createBool :: String -> Maybe Tree +createBool "#f" = Just (Leaf (Boolean False)) createBool "#t" = Just (Leaf (Boolean True)) -createBool ('#':'t':xs) | xs == ")" = Just (Leaf (Boolean True)) - | dropWhile skipableChar xs == ")" = +createBool "#f)" = Just (Leaf (Boolean False)) +createBool "#t)" = Just (Leaf (Boolean True)) +createBool ('#':'t':xs) | dropWhile skipableChar xs == ")" = Just (Leaf (Boolean True)) -createBool "#f" = Just (Leaf (Boolean False)) -createBool ('#':'f':xs) | xs == ")" = Just (Leaf (Boolean False)) - | dropWhile skipableChar xs == ")" = + | otherwise = Nothing +createBool ('#':'f':xs) | dropWhile skipableChar xs == ")" = Just (Leaf (Boolean False)) + | otherwise = Nothing createBool _ = Nothing treeFromAtom :: String -> String -> Maybe Tree