diff --git a/app/ArgValidation.hs b/app/ArgValidation.hs index 063a336..1464c7a 100644 --- a/app/ArgValidation.hs +++ b/app/ArgValidation.hs @@ -6,8 +6,6 @@ module ArgValidation import qualified Data.Text as T -import Exp - data ArgValidation = IsEPar | IsEApplyFlat diff --git a/app/ExceptionFuncs.hs b/app/ExceptionFuncs.hs index c59c27d..e6d7c2c 100644 --- a/app/ExceptionFuncs.hs +++ b/app/ExceptionFuncs.hs @@ -7,37 +7,36 @@ module ExceptionFuncs import qualified Data.ByteString.Lazy.Char8 as BS import Control.Exception - -import ArgValidation import Data.Text as T import TextShow +import ArgValidation import Exceptions -import Exp -import Reproduces +import IsTrace import Resolved import ResolvedFuncs -errorMessageFromFilterStr :: (Reproduces a) => BS.ByteString -> FilterException a -> Builder +errorMessageFromFilterStr :: IsTrace trc => + BS.ByteString -> FilterException trc -> Builder errorMessageFromFilterStr origTxt raw@(Can'tResolveAsBool rep _ _) = (showb raw) <> " in " - <> (fromText $ reproduce rep $ T.pack $ BS.unpack origTxt) + <> (trace (T.pack $ BS.unpack origTxt) rep) errorMessageFromFilterStr origTxt raw@(DuplicateName rep _) = (showb raw) <> " in " - <> (fromText $ reproduce rep $ T.pack $ BS.unpack origTxt) + <> (trace (T.pack $ BS.unpack origTxt) rep) errorMessageFromFilterStr origTxt raw@(FuncArgWrongType rep _ _ _ _) = (showb raw) <> " in " - <> (fromText $ reproduce rep $ T.pack $ BS.unpack origTxt) + <> (trace (T.pack $ BS.unpack origTxt) rep) errorMessageFromFilterStr origTxt raw@(FuncNameNotRecognized rep _) = (showb raw) <> " in " - <> (fromText $ reproduce rep $ T.pack $ BS.unpack origTxt) + <> (trace (T.pack $ BS.unpack origTxt) rep) errorMessageFromFilterStr origTxt raw@(FuncWrongNumArgs rep _ _ _) = (showb raw) <> " in " - <> (fromText $ reproduce rep $ T.pack $ BS.unpack origTxt) + <> (trace (T.pack $ BS.unpack origTxt) rep) errorMessageFromFilterStr _ raw = showb raw - -toErrorMessage :: (Reproduces a) => BS.ByteString -> TSException a -> Builder +toErrorMessage :: IsTrace trc => + BS.ByteString -> TSException trc -> Builder toErrorMessage filterStr (Filter filterExc) = errorMessageFromFilterStr filterStr filterExc toErrorMessage _ (Other otherExc) = showb otherExc diff --git a/app/Exceptions.hs b/app/Exceptions.hs index 6ab5907..f261a13 100644 --- a/app/Exceptions.hs +++ b/app/Exceptions.hs @@ -12,14 +12,13 @@ import Control.Exception import Data.Text as T import Data.Text.Lazy (toStrict) import Data.Typeable +import TextShow -import Exp import ResolvedType -import TextShow type EitherF a result = Either (FilterException a) result --- TODO: give this 'a' parameters for all constructors, implement HasTrace, and use that in +-- TODO: give this 'a' parameters for all constructors, implement IsTrace, and use that in -- toErrorMessage data FilterException a = Can'tResolveAsBool a Text ResolvedType diff --git a/app/Exp.hs b/app/Exp.hs deleted file mode 100644 index ef4abda..0000000 --- a/app/Exp.hs +++ /dev/null @@ -1,59 +0,0 @@ -module Exp - ( - Exp(..) - ) where - -import qualified Data.List as L -import qualified Data.Map as M -import qualified Data.Text as T -import Debug.Trace -import TextShow.Debug.Trace - -import ASTShow -import FData -import HasTrace -import Lit -import RawExp -import Reproduces - -data Exp a = - -- Parentheses - EPar a (Exp a) - -- Function application - | EApplyFlat a [Exp a] -- converted to from Raw - -- List - | EList a [Exp a] - -- Literals - | ELit a Lit - | EFile a - -- Syntax - | EIdent a T.Text - deriving (Foldable, Functor, Traversable) - -instance Eq (Exp a) where - (EPar _ x) == (EPar _ x') = x == x' - (EApplyFlat _ xs) == (EApplyFlat _ xs') = xs == xs' - (EList _ xs) == (EList _ xs') = xs == xs' - (ELit _ x) == (ELit _ x') = x == x' - (EIdent _ x) == (EIdent _ x') = x == x' - _ == _ = False - -instance HasTrace Exp where - getTrace :: Exp a -> a - getTrace (EPar a _) = a - getTrace (EApplyFlat a _) = a - -- getTrace (EPartiallyApplied a _ _) = a - getTrace (EList a _) = a - getTrace (ELit a _) = a - getTrace (EFile a) = a - getTrace (EIdent a _) = a - --- instance ASTShow (Exp a) where - -- errorShow (EPar _ x) = "( " <> errorShow x <> ")" - -- errorShow (EApplyFlat _ xs) = T.intercalate " " $ errorShow <$> xs - -- errorShow (EList _ xs) = "[ " <> (T.intercalate " " $ errorShow <$> xs) <> "]" - -- errorShow (ELit _ x) = T.pack $ show x - -- errorShow (EFile _) = "file" - -- errorShow (EIdent _ name) = name - -- astShow x = prettyShow x - diff --git a/app/ExpFuncs.hs b/app/ExpFuncs.hs index 46b6476..defa45c 100644 --- a/app/ExpFuncs.hs +++ b/app/ExpFuncs.hs @@ -12,7 +12,7 @@ import qualified Data.Text as T import ArgValidation import Exceptions import Exp -import HasTrace +import IsTrace import qualified Lit as LT import RawExp import RawExpFuncs diff --git a/app/FunctionDefinition.hs b/app/FunctionDefinition.hs index f5f968d..57d0c5d 100644 --- a/app/FunctionDefinition.hs +++ b/app/FunctionDefinition.hs @@ -8,12 +8,13 @@ import qualified Data.Text as T import Exceptions import FData +import IsTrace -data FunctionDefinition typeDef exprDef traceType = +data FunctionDefinition typeDef exprDef trc = FunctionDefinition { funcName :: T.Text , expectedTypes :: [typeDef] - , funcApply :: (Semigroup traceType, Show traceType) => FData -> [exprDef traceType] -> EitherF traceType (exprDef traceType) + , funcApply :: IsTrace trc => FData -> [exprDef trc] -> EitherF trc (exprDef trc) } instance Eq (FunctionDefinition a b c) where diff --git a/app/FunctionType.hs b/app/FunctionType.hs index a43a118..a1e3d93 100644 --- a/app/FunctionType.hs +++ b/app/FunctionType.hs @@ -11,7 +11,6 @@ import qualified Data.List as L import TextShow.Debug.Trace import ArgValidation -import Exp import FunctionDefinition import FData import RawExp diff --git a/app/Functions.hs b/app/Functions.hs index 9817979..a888cc6 100644 --- a/app/Functions.hs +++ b/app/Functions.hs @@ -9,7 +9,7 @@ module Functions import qualified Data.Text as T import FData -import HasTrace +import IsTrace import Lit import Resolved import ResolvedFuncs @@ -40,72 +40,73 @@ functions = [ , FunctionDefinition "map" [TPartiallyApplied [TGeneric "X"], TList (TGeneric "X")] mapFunc ] -orFunc :: Show a => FData -> [Resolved a] -> EitherF a (Resolved a) +orFunc :: IsTrace trc => FData -> [Resolved trc] -> EitherF trc (Resolved trc) orFunc _ [RLit a (LBool False), RLit _ (LBool False)] = Right $ RLit a $ LBool False orFunc _ [RLit a (LBool _), RLit _ (LBool _)] = Right $ RLit a $ LBool True -andFunc :: Show a => FData -> [Resolved a] -> EitherF a (Resolved a) +andFunc :: IsTrace trc => FData -> [Resolved trc] -> EitherF trc (Resolved trc) andFunc _ [RLit a (LBool True), RLit _ (LBool True)] = Right $ RLit a $ LBool True andFunc _ [RLit a (LBool _), RLit _ (LBool _)] = Right $ RLit a $ LBool False -eqsFunc :: (Semigroup a, Show a) => FData -> [Resolved a] -> EitherF a (Resolved a) -eqsFunc _ [x, y] = Right $ RLit (getTrace x) $ LBool (x == y) +eqsFunc :: IsTrace trc => (IsTrace trc) => FData -> [Resolved trc] -> EitherF trc (Resolved trc) +eqsFunc _ [x, y] = Right $ RLit (getRange x) $ LBool (x == y) -plusFunc :: Show a => FData -> [Resolved a] -> EitherF a (Resolved a) +plusFunc :: IsTrace trc => FData -> [Resolved trc] -> EitherF trc (Resolved trc) plusFunc _ [RLit a (LInteger x), RLit _ (LInteger y)] = Right $ RLit a $ LInteger $ x + y -minusFunc :: Show a => FData -> [Resolved a] -> EitherF a (Resolved a) +minusFunc :: IsTrace trc => FData -> [Resolved trc] -> EitherF trc (Resolved trc) minusFunc _ [RLit a (LInteger x), RLit _ (LInteger y)] = Right $ RLit a $ LInteger $ x - y -inFunc :: Show a => FData -> [Resolved a] -> EitherF a (Resolved a) +inFunc :: IsTrace trc => FData -> [Resolved trc] -> EitherF trc (Resolved trc) inFunc _ [x, RList a xs] = Right $ RLit a $ LBool $ elem x xs -notFunc :: Show a => FData -> [Resolved a] -> EitherF a (Resolved a) +notFunc :: IsTrace trc => FData -> [Resolved trc] -> EitherF trc (Resolved trc) notFunc _ [RLit a (LBool True)] = Right $ RLit a $ LBool False notFunc _ [RLit a (LBool False)] = Right $ RLit a $ LBool True -basenameFunc :: Show a => FData -> [Resolved a] -> EitherF a (Resolved a) +basenameFunc :: IsTrace trc => FData -> [Resolved trc] -> EitherF trc (Resolved trc) basenameFunc fData [RFile a] = Right $ RLit a $ LString $ basename fData -isFileFunc :: Show a => FData -> [Resolved a] -> EitherF a (Resolved a) +isFileFunc :: IsTrace trc => FData -> [Resolved trc] -> EitherF trc (Resolved trc) isFileFunc fData [RFile a] = Right $ RLit a $ LBool $ (fileType fData) == FileFileType -isDirFunc :: Show a => FData -> [Resolved a] -> EitherF a (Resolved a) +isDirFunc :: IsTrace trc => FData -> [Resolved trc] -> EitherF trc (Resolved trc) isDirFunc fData [RFile a] = Right $ RLit a $ LBool $ (fileType fData) == DirFileType -parentsFunc :: Show a => FData -> [Resolved a] -> EitherF a (Resolved a) +parentsFunc :: IsTrace trc => FData -> [Resolved trc] -> EitherF trc (Resolved trc) parentsFunc fData [RFile a] = Right $ RList a $ ((RLit a) . LString) <$> (parents fData) -startsWithFunc :: Show a => FData -> [Resolved a] -> EitherF a (Resolved a) +startsWithFunc :: IsTrace trc => FData -> [Resolved trc] -> EitherF trc (Resolved trc) startsWithFunc _ [RLit a (LString searchStr), RLit _ (LString str)] = Right $ RLit a $ LBool $ T.isPrefixOf searchStr str -endsWithFunc :: Show a => FData -> [Resolved a] -> EitherF a (Resolved a) +endsWithFunc :: IsTrace trc => FData -> [Resolved trc] -> EitherF trc (Resolved trc) endsWithFunc _ [RLit a (LString searchStr), RLit _ (LString str)] = Right $ RLit a $ LBool $ T.isSuffixOf searchStr str -occursInFunc :: Show a => FData -> [Resolved a] -> EitherF a (Resolved a) +occursInFunc :: IsTrace trc => FData -> [Resolved trc] -> EitherF trc (Resolved trc) occursInFunc _ [RLit a (LString searchStr), RLit _ (LString str)] = Right $ RLit a $ LBool $ T.isInfixOf searchStr str -mapFunc :: (Show a, Semigroup a) => FData -> [Resolved a] -> EitherF a (Resolved a) +mapFunc :: IsTrace trc => FData -> [Resolved trc] -> EitherF trc (Resolved trc) mapFunc fData [f@(RPartiallyApplied _ _ _), RList a xs] = let mapped = mapM (\x -> tryToResolvePartial fData f [x]) xs in RList a <$> mapped -allFunc :: (Show a, Semigroup a) => FData -> [Resolved a] -> EitherF a (Resolved a) +allFunc :: IsTrace trc => FData -> [Resolved trc] -> EitherF trc (Resolved trc) allFunc fData [f@(RPartiallyApplied _ _ _), RList a xs] = let asBools = mapM (\x -> convertToBool =<< tryToResolvePartial fData f [x]) xs in (\xs' -> RLit a $ LBool $ all id xs') <$> asBools -anyFunc :: (Semigroup a, Show a) => FData -> [Resolved a] -> EitherF a (Resolved a) +anyFunc :: IsTrace trc => FData -> [Resolved trc] -> EitherF trc (Resolved trc) anyFunc fData [f@(RPartiallyApplied _ _ _), RList a xs] = let asBools = mapM (\x -> convertToBool =<< tryToResolvePartial fData f [x]) xs in (\xs' -> RLit a $ LBool $ any id xs') <$> asBools + diff --git a/app/HasTrace.hs b/app/HasTrace.hs deleted file mode 100644 index e24cd64..0000000 --- a/app/HasTrace.hs +++ /dev/null @@ -1,7 +0,0 @@ -module HasTrace ( - HasTrace(..) -) where - -class HasTrace d where - getTrace :: Semigroup a => (d a) -> a - diff --git a/app/Reproduces.hs b/app/IsTrace.hs similarity index 72% rename from app/Reproduces.hs rename to app/IsTrace.hs index 6c9204a..ebda623 100644 --- a/app/Reproduces.hs +++ b/app/IsTrace.hs @@ -1,19 +1,17 @@ -module Reproduces ( - Reproduces - , reproduce +module IsTrace ( + IsTrace(..) , reproduceFromLineCol ) where -import qualified Data.ByteString.Lazy.Char8 as BS import qualified Data.List as L -import Data.Maybe import qualified Data.Text as T +import TextShow -class Reproduces a where - reproduce :: a -> T.Text -> T.Text +class (Semigroup a) => IsTrace a where + trace :: Semigroup a => T.Text -> a -> Builder -reproduceFromLineCol :: (Int, Int) -> (Int, Int) -> T.Text -> T.Text -reproduceFromLineCol (lineX, colX) (lineY, colY) origTxt = +reproduceFromLineCol :: T.Text -> (Int, Int) -> (Int, Int) -> Builder +reproduceFromLineCol origTxt (lineX, colX) (lineY, colY) = let asLines = T.lines origTxt lines = take (lineY - lineX + 1) $ drop (lineX - 1) asLines lines' = case lines of @@ -28,5 +26,5 @@ reproduceFromLineCol (lineX, colX) (lineY, colY) origTxt = firstLine' = T.drop colY firstLine lastLine' = T.take colY lastLine in firstLine':(midLines ++ [lastLine']) - in T.unlines lines' + in fromText $ T.unlines lines' diff --git a/app/Lexer.x b/app/Lexer.x index 267ae74..08b7b7c 100644 --- a/app/Lexer.x +++ b/app/Lexer.x @@ -23,7 +23,7 @@ import qualified Data.Text as T import Data.ByteString.Lazy.Char8 (ByteString, length, lines) import Data.Text.Encoding -import Reproduces +import IsTrace } -- In the middle, we insert our definitions for the lexer, which will generate the lexemes for our grammar. @@ -86,16 +86,16 @@ getFullRange filterStr = stop' = AlexPn 0 (L.length strLines) (fromIntegral $ length $ last strLines) in Range start' stop' -instance Reproduces Range where - reproduce (Range (AlexPn _ lineX colX) (AlexPn _ lineY colY)) txt = - reproduceFromLineCol (lineX, colX) (lineY, colY) txt +instance Semigroup Range where + Range a _ <> Range _ b = Range a b + +instance IsTrace Range where + trace txt (Range (AlexPn _ lineX colX) (AlexPn _ lineY colY)) = + reproduceFromLineCol txt (lineX, colX) (lineY, colY) -- | Performs the union of two ranges by creating a new range starting at the -- start position of the first range, and stopping at the stop position of the -- second range. -instance Semigroup Range where - Range a _ <> Range _ b = Range a b - data RangedToken = RangedToken { rtToken :: Token , rtRange :: Range diff --git a/app/Output.hs b/app/Output.hs index 2774bb6..77f7a30 100644 --- a/app/Output.hs +++ b/app/Output.hs @@ -13,8 +13,6 @@ import System.Console.ANSI import System.Directory.Tree import System.FilePath -import Exp - singleInd :: String singleInd = " " diff --git a/app/Parser.hs b/app/Parser.hs index ca29b42..9a2daa0 100644 --- a/app/Parser.hs +++ b/app/Parser.hs @@ -20,7 +20,7 @@ import Control.Monad (ap) -- parser produced by Happy Version 1.20.1.1 -data HappyAbsSyn +data HappyAbsSyn = HappyTerminal (X.RangedToken) | HappyErrorToken Prelude.Int | HappyAbsSyn4 (RawExp X.Range) @@ -37,12 +37,12 @@ data HappyAbsSyn - /type M a = .../, then /(HappyReduction M)/ - is not allowed. But Happy is a - code-generator that can just substitute it. -type HappyReduction m = - Prelude.Int +type HappyReduction m = + Prelude.Int -> (X.RangedToken) -> HappyState (X.RangedToken) (HappyStk HappyAbsSyn -> m HappyAbsSyn) - -> [HappyState (X.RangedToken) (HappyStk HappyAbsSyn -> m HappyAbsSyn)] - -> HappyStk HappyAbsSyn + -> [HappyState (X.RangedToken) (HappyStk HappyAbsSyn -> m HappyAbsSyn)] + -> HappyStk HappyAbsSyn -> m HappyAbsSyn -} @@ -82,11 +82,11 @@ action_0, action_33, action_34, action_35 :: () => Prelude.Int -> ({-HappyReduction (X.Alex) = -} - Prelude.Int + Prelude.Int -> (X.RangedToken) -> HappyState (X.RangedToken) (HappyStk HappyAbsSyn -> (X.Alex) HappyAbsSyn) - -> [HappyState (X.RangedToken) (HappyStk HappyAbsSyn -> (X.Alex) HappyAbsSyn)] - -> HappyStk HappyAbsSyn + -> [HappyState (X.RangedToken) (HappyStk HappyAbsSyn -> (X.Alex) HappyAbsSyn)] + -> HappyStk HappyAbsSyn -> (X.Alex) HappyAbsSyn) happyReduce_1, @@ -112,11 +112,11 @@ happyReduce_1, happyReduce_21, happyReduce_22, happyReduce_23 :: () => ({-HappyReduction (X.Alex) = -} - Prelude.Int + Prelude.Int -> (X.RangedToken) -> HappyState (X.RangedToken) (HappyStk HappyAbsSyn -> (X.Alex) HappyAbsSyn) - -> [HappyState (X.RangedToken) (HappyStk HappyAbsSyn -> (X.Alex) HappyAbsSyn)] - -> HappyStk HappyAbsSyn + -> [HappyState (X.RangedToken) (HappyStk HappyAbsSyn -> (X.Alex) HappyAbsSyn)] + -> HappyStk HappyAbsSyn -> (X.Alex) HappyAbsSyn) happyExpList :: Happy_Data_Array.Array Prelude.Int Prelude.Int @@ -349,14 +349,14 @@ happyReduction_1 (HappyAbsSyn4 happy_var_1) = HappyAbsSyn4 (happy_var_1 ) -happyReduction_1 _ = notHappyAtAll +happyReduction_1 _ = notHappyAtAll happyReduce_2 = happySpecReduce_1 4 happyReduction_2 happyReduction_2 (HappyAbsSyn6 happy_var_1) = HappyAbsSyn4 (RawApply (info (L.head happy_var_1) <> info (L.last happy_var_1)) (L.reverse happy_var_1) ) -happyReduction_2 _ = notHappyAtAll +happyReduction_2 _ = notHappyAtAll happyReduce_3 = happySpecReduce_3 5 happyReduction_3 happyReduction_3 (HappyTerminal happy_var_3) @@ -365,14 +365,14 @@ happyReduction_3 (HappyTerminal happy_var_3) = HappyAbsSyn4 (RawPar (X.rtRange happy_var_1 <> X.rtRange happy_var_3) happy_var_2 ) -happyReduction_3 _ _ _ = notHappyAtAll +happyReduction_3 _ _ _ = notHappyAtAll happyReduce_4 = happySpecReduce_1 5 happyReduction_4 happyReduction_4 (HappyAbsSyn7 happy_var_1) = HappyAbsSyn4 (RawLit (snd happy_var_1) (fst happy_var_1) ) -happyReduction_4 _ = notHappyAtAll +happyReduction_4 _ = notHappyAtAll happyReduce_5 = happySpecReduce_3 5 happyReduction_5 happyReduction_5 (HappyTerminal happy_var_3) @@ -381,14 +381,14 @@ happyReduction_5 (HappyTerminal happy_var_3) = HappyAbsSyn4 (RawList (X.rtRange happy_var_1 <> X.rtRange happy_var_3) happy_var_2 ) -happyReduction_5 _ _ _ = notHappyAtAll +happyReduction_5 _ _ _ = notHappyAtAll happyReduce_6 = happySpecReduce_1 5 happyReduction_6 happyReduction_6 (HappyAbsSyn9 happy_var_1) = HappyAbsSyn4 (RawIdent (snd happy_var_1) (fst happy_var_1) ) -happyReduction_6 _ = notHappyAtAll +happyReduction_6 _ = notHappyAtAll happyReduce_7 = happyReduce 4 5 happyReduction_7 happyReduction_7 ((HappyAbsSyn4 happy_var_4) `HappyStk` @@ -406,7 +406,7 @@ happyReduction_8 (HappyAbsSyn4 happy_var_2) = HappyAbsSyn6 (happy_var_2 : happy_var_1 ) -happyReduction_8 _ _ = notHappyAtAll +happyReduction_8 _ _ = notHappyAtAll happyReduce_9 = happySpecReduce_2 6 happyReduction_9 happyReduction_9 (HappyAbsSyn4 happy_var_2) @@ -414,49 +414,49 @@ happyReduction_9 (HappyAbsSyn4 happy_var_2) = HappyAbsSyn6 ([ happy_var_2, happy_var_1 ] ) -happyReduction_9 _ _ = notHappyAtAll +happyReduction_9 _ _ = notHappyAtAll happyReduce_10 = happySpecReduce_1 7 happyReduction_10 happyReduction_10 (HappyAbsSyn7 happy_var_1) = HappyAbsSyn7 (happy_var_1 ) -happyReduction_10 _ = notHappyAtAll +happyReduction_10 _ = notHappyAtAll happyReduce_11 = happySpecReduce_1 7 happyReduction_11 happyReduction_11 (HappyTerminal happy_var_1) = HappyAbsSyn7 (unTok happy_var_1 (\rng (X.String s) -> (LString $ unQuote s, rng)) ) -happyReduction_11 _ = notHappyAtAll +happyReduction_11 _ = notHappyAtAll happyReduce_12 = happySpecReduce_1 7 happyReduction_12 happyReduction_12 (HappyTerminal happy_var_1) = HappyAbsSyn7 (unTok happy_var_1 (\rng (X.Integer i) -> (LInteger i, rng)) ) -happyReduction_12 _ = notHappyAtAll +happyReduction_12 _ = notHappyAtAll happyReduce_13 = happySpecReduce_1 8 happyReduction_13 happyReduction_13 (HappyTerminal happy_var_1) = HappyAbsSyn7 ((LBool False, X.rtRange happy_var_1) ) -happyReduction_13 _ = notHappyAtAll +happyReduction_13 _ = notHappyAtAll happyReduce_14 = happySpecReduce_1 8 happyReduction_14 happyReduction_14 (HappyTerminal happy_var_1) = HappyAbsSyn7 ((LBool True, X.rtRange happy_var_1) ) -happyReduction_14 _ = notHappyAtAll +happyReduction_14 _ = notHappyAtAll happyReduce_15 = happySpecReduce_1 9 happyReduction_15 happyReduction_15 (HappyTerminal happy_var_1) = HappyAbsSyn9 (unTok happy_var_1 (\rng (X.Identifier n) -> (n, rng)) ) -happyReduction_15 _ = notHappyAtAll +happyReduction_15 _ = notHappyAtAll happyReduce_16 = happySpecReduce_3 10 happyReduction_16 happyReduction_16 (HappyAbsSyn4 happy_var_3) @@ -465,7 +465,7 @@ happyReduction_16 (HappyAbsSyn4 happy_var_3) = HappyAbsSyn10 ((fst happy_var_1, happy_var_3) ) -happyReduction_16 _ _ _ = notHappyAtAll +happyReduction_16 _ _ _ = notHappyAtAll happyReduce_17 = happySpecReduce_3 11 happyReduction_17 happyReduction_17 _ @@ -474,7 +474,7 @@ happyReduction_17 _ = HappyAbsSyn11 (happy_var_2 : happy_var_1 ) -happyReduction_17 _ _ _ = notHappyAtAll +happyReduction_17 _ _ _ = notHappyAtAll happyReduce_18 = happySpecReduce_2 11 happyReduction_18 happyReduction_18 (HappyAbsSyn10 happy_var_2) @@ -482,7 +482,7 @@ happyReduction_18 (HappyAbsSyn10 happy_var_2) = HappyAbsSyn11 (happy_var_2 : happy_var_1 ) -happyReduction_18 _ _ = notHappyAtAll +happyReduction_18 _ _ = notHappyAtAll happyReduce_19 = happySpecReduce_2 11 happyReduction_19 happyReduction_19 _ @@ -490,14 +490,14 @@ happyReduction_19 _ = HappyAbsSyn11 ([ happy_var_1 ] ) -happyReduction_19 _ _ = notHappyAtAll +happyReduction_19 _ _ = notHappyAtAll happyReduce_20 = happySpecReduce_1 11 happyReduction_20 happyReduction_20 (HappyAbsSyn10 happy_var_1) = HappyAbsSyn11 ([ happy_var_1 ] ) -happyReduction_20 _ = notHappyAtAll +happyReduction_20 _ = notHappyAtAll happyReduce_21 = happySpecReduce_3 12 happyReduction_21 happyReduction_21 (HappyAbsSyn4 happy_var_3) @@ -506,14 +506,14 @@ happyReduction_21 (HappyAbsSyn4 happy_var_3) = HappyAbsSyn12 (happy_var_3 : happy_var_1 ) -happyReduction_21 _ _ _ = notHappyAtAll +happyReduction_21 _ _ _ = notHappyAtAll happyReduce_22 = happySpecReduce_1 12 happyReduction_22 happyReduction_22 (HappyAbsSyn4 happy_var_1) = HappyAbsSyn12 ([ happy_var_1 ] ) -happyReduction_22 _ = notHappyAtAll +happyReduction_22 _ = notHappyAtAll happyReduce_23 = happySpecReduce_0 12 happyReduction_23 happyReduction_23 = HappyAbsSyn12 @@ -521,7 +521,7 @@ happyReduction_23 = HappyAbsSyn12 ) happyNewToken action sts stk - = lexer(\tk -> + = lexer(\tk -> let cont i = action i i tk (HappyState action) sts stk in case tk of { X.RangedToken X.EOF _ -> action 27 27 tk (HappyState action) sts stk; @@ -684,7 +684,7 @@ happyParse start_state = happyNewToken start_state notHappyAtAll notHappyAtAll -- the stack in this case. happyAccept (1) tk st sts (_ `HappyStk` ans `HappyStk` _) = happyReturn1 ans -happyAccept j tk st sts (HappyStk ans _) = +happyAccept j tk st sts (HappyStk ans _) = (happyReturn1 ans) ----------------------------------------------------------------------------- @@ -859,7 +859,7 @@ happyGoto action j tk st = action j j tk (HappyState action) -- parse error if we are in recovery and we fail again happyFail explist (1) tk old_st _ stk@(x `HappyStk` _) = let i = (case x of { HappyErrorToken (i) -> i }) in --- trace "failing" $ +-- trace "failing" $ happyError_ explist i tk {- We don't need state discarding for our restricted implementation of @@ -867,7 +867,7 @@ happyFail explist (1) tk old_st _ stk@(x `HappyStk` _) = for now --SDM -- discard a state -happyFail ERROR_TOK tk old_st CONS(HAPPYSTATE(action),sts) +happyFail ERROR_TOK tk old_st CONS(HAPPYSTATE(action),sts) (saved_tok `HappyStk` _ `HappyStk` stk) = -- trace ("discarding state, depth " ++ show (length stk)) $ DO_ACTION(action,ERROR_TOK,tk,sts,(saved_tok`HappyStk`stk)) @@ -894,7 +894,7 @@ notHappyAtAll = Prelude.error "Internal Happy error\n" ----------------------------------------------------------------------------- --- Seq-ing. If the --strict flag is given, then Happy emits +-- Seq-ing. If the --strict flag is given, then Happy emits -- happySeq = happyDoSeq -- otherwise it emits -- happySeq = happyDontSeq diff --git a/app/Parser.y b/app/Parser.y index 6dd7378..b39af7a 100644 --- a/app/Parser.y +++ b/app/Parser.y @@ -13,6 +13,7 @@ import qualified Lexer as X import Lit import qualified ParseException as PE import RawExp +import Trace } %name parseTreeSurgeon exp @@ -52,6 +53,9 @@ import RawExp %% +-- traceExp :: { RawExp (Trace X.Range) } +-- : exp { mkTrace <$> $1 } + exp :: { RawExp X.Range } : single { $1 } | applyParse { RawApply (info (L.head $1) <> info (L.last $1)) (L.reverse $1) } diff --git a/app/RawExp.hs b/app/RawExp.hs index 97c5615..bd8f6a4 100644 --- a/app/RawExp.hs +++ b/app/RawExp.hs @@ -4,6 +4,7 @@ module RawExp ( NamedExp(..) , RawExp(..) + , getRange ) where import qualified Data.Text as T @@ -11,7 +12,7 @@ import qualified Data.List as L import TextShow import ASTShow -import HasTrace +import IsTrace import Lit type NamedExp a = (T.Text, RawExp a) @@ -29,15 +30,25 @@ data RawExp a = -- Syntax | RawIdent a T.Text | RawLet a [NamedExp a] (RawExp a) - deriving (Foldable) + deriving Foldable -instance HasTrace RawExp where - getTrace (RawPar a _) = a - getTrace (RawApply a _) = a - getTrace (RawList a _) = a - getTrace (RawLit a _) = a - getTrace (RawIdent a _) = a - getTrace (RawLet a _ _) = a +instance Functor RawExp where + fmap f (RawPar a expr) = RawPar (f a) (fmap f expr) + fmap f (RawApply a xs) = RawApply (f a) (fmap f <$> xs) + fmap f (RawList a xs) = RawList (f a) (fmap f <$> xs) + fmap f (RawLit a lit) = RawLit (f a) lit + fmap f (RawIdent a txt) = RawIdent (f a) txt + fmap f (RawLet a namedExprs expr) = + let namedExprs' = (\(t, e) -> (t, fmap f e)) <$> namedExprs + in RawLet (f a) namedExprs' (fmap f expr) + +getRange :: RawExp a -> a +getRange (RawPar a _) = a +getRange (RawApply a _) = a +getRange (RawList a _) = a +getRange (RawLit a _) = a +getRange (RawIdent a _) = a +getRange (RawLet a _ _) = a instance ASTShow (RawExp a) where astShow = astShow' diff --git a/app/RawExpFuncs.hs b/app/RawExpFuncs.hs index b3cb348..b6c7494 100644 --- a/app/RawExpFuncs.hs +++ b/app/RawExpFuncs.hs @@ -9,13 +9,15 @@ import qualified Data.List as L import qualified Data.Map as M import qualified Data.Text as T +import qualified Lexer as X import Exceptions -import HasTrace +import IsTrace import InfixOperators +import IsTrace import RawExp -import Reproduces +import Trace -simplifyRawExp :: (Semigroup a, Reproduces a) => RawExp a -> EitherF a (RawExp a) +simplifyRawExp :: IsTrace trc => RawExp trc -> EitherF trc (RawExp trc) simplifyRawExp expr = do namesRemoved <- removeNames M.empty expr let infixesResolved = resolveInfixes namesRemoved @@ -31,8 +33,8 @@ setRawExpRange a (RawLit _ x) = RawLit a x setRawExpRange a (RawIdent _ x) = RawIdent a x setRawExpRange a (RawLet _ x y) = RawLet a x y -removeNames :: (Reproduces a) => - M.Map T.Text (NamedExp a) -> RawExp a -> EitherF a (RawExp a) +removeNames :: (IsTrace trc) => + M.Map T.Text (NamedExp trc) -> RawExp trc -> EitherF trc (RawExp trc) removeNames nDefs (RawPar a x) = RawPar a <$> (removeNames nDefs x) removeNames nDefs (RawApply a xs) = RawApply a <$> mapM (removeNames nDefs) xs removeNames nDefs (RawList a xs) = RawList a <$> mapM (removeNames nDefs) xs @@ -67,18 +69,18 @@ namesMatchExp' (x:xs) ys acc = ++ filter (\n -> fst n == fst x) ys namesMatchExp' [] ys acc = acc -resolveInfixes :: (Semigroup a) => RawExp a -> RawExp a +resolveInfixes :: IsTrace a => RawExp a -> RawExp a resolveInfixes x = baseToLeafTraverse resolveAllInfixesForExp x -resolveAllInfixesForExp :: (Semigroup a) => RawExp a -> RawExp a +resolveAllInfixesForExp :: IsTrace a => RawExp a -> RawExp a resolveAllInfixesForExp x = L.foldl' (\acc op -> resolveInfixesForOperator op acc) x infixOperators -resolveInfixesForOperator :: (Semigroup a) => InfixOperator -> RawExp a -> RawExp a +resolveInfixesForOperator :: IsTrace a => InfixOperator -> RawExp a -> RawExp a resolveInfixesForOperator (op, LeftAssoc) (RawApply a xs) = let xs' = reverse $ resolveInfixesForOperator' op [] $ reverse xs in RawApply a xs' @@ -87,26 +89,26 @@ resolveInfixesForOperator (op, RightAssoc) (RawApply a xs) = in RawApply a xs' resolveInfixesForOperator _ x = x -resolveInfixesForOperator' :: (Semigroup a) => T.Text -> [RawExp a] -> [RawExp a] -> [RawExp a] +resolveInfixesForOperator' :: IsTrace a => T.Text -> [RawExp a] -> [RawExp a] -> [RawExp a] resolveInfixesForOperator' op acc (x@(RawIdent _ name):xs) = if op == name then let arg0 = case acc of [] -> - let a' = L.foldl' (<>) (getTrace x) (getTrace <$> xs) + let a' = L.foldl' (<>) (getRange x) (getRange <$> xs) in RawApply a' $ x:xs [x'] -> x' xs' -> let xs'' = reverse xs' - a' = L.foldl' (<>) (getTrace $ head xs'') (getTrace <$> tail xs'') + a' = L.foldl' (<>) (getRange $ head xs'') (getRange <$> tail xs'') in RawApply a' xs'' arg1 = case xs of [] -> let xs' = reverse (x:acc) - a' = L.foldl' (<>) (getTrace $ head xs') (getTrace <$> tail xs') + a' = L.foldl' (<>) (getRange $ head xs') (getRange <$> tail xs') in RawApply a' $ xs' [x'] -> x' - xs' -> let a' = L.foldl' (<>) (getTrace $ head xs') (getTrace <$> tail xs') + xs' -> let a' = L.foldl' (<>) (getRange $ head xs') (getRange <$> tail xs') in RawApply a' xs' in [x, arg0, arg1] else diff --git a/app/Resolved.hs b/app/Resolved.hs index 7b830f3..8f895e1 100644 --- a/app/Resolved.hs +++ b/app/Resolved.hs @@ -2,6 +2,7 @@ module Resolved ( Resolved(..) , ResolvedFuncDef + , getRange ) where import qualified Data.List as L @@ -9,7 +10,7 @@ import TextShow import ASTShow import FunctionDefinition -import HasTrace +import IsTrace import ResolvedType import Lit @@ -21,6 +22,12 @@ data Resolved a = | RLit a Lit | RFile a +getRange :: Resolved a -> a +getRange (RPartiallyApplied a _ _) = a +getRange (RList a _) = a +getRange (RLit a _) = a +getRange (RFile a) = a + instance Eq (Resolved a) where (RPartiallyApplied _ funcDef args) == (RPartiallyApplied _ funcDef' args') = funcDef == funcDef' && args == args' (RList _ xs) == (RList _ xs') = xs == xs' @@ -28,14 +35,6 @@ instance Eq (Resolved a) where (RFile _) == (RFile _) = True _ == _ = False -instance HasTrace Resolved where - getTrace (RPartiallyApplied a _ args) = - L.foldl' (<>) a (getTrace <$> args) - getTrace (RList a xs) = - L.foldl' (<>) a (getTrace <$> xs) - getTrace (RLit a _) = a - getTrace (RFile a) = a - instance ASTShow (Resolved a) where astShow = astShow' diff --git a/app/ResolvedFuncs.hs b/app/ResolvedFuncs.hs index a98cfb6..941d91f 100644 --- a/app/ResolvedFuncs.hs +++ b/app/ResolvedFuncs.hs @@ -13,10 +13,9 @@ import qualified Data.Map as M import qualified Data.Text as T import Exceptions -import Exp import FunctionDefinition import FData -import HasTrace +import IsTrace import Lit import SimpleExp import Resolved @@ -38,7 +37,7 @@ fileVariableName = "file" -- have called identsToFunctionApplications on our Exp a) -- If we are assuming that EIdents -simpleExpToResolved :: (Semigroup a, Show a) => [ResolvedFuncDef a] -> FData -> SimpleExp a -> EitherF a (Resolved a) +simpleExpToResolved :: IsTrace a => [ResolvedFuncDef a] -> FData -> SimpleExp a -> EitherF a (Resolved a) simpleExpToResolved funcDefs fData (SimpleApply a xs) = let xs' = mapM (simpleExpToResolved funcDefs fData) xs in (\(partialApply:funcArgs) -> tryToResolvePartial fData partialApply funcArgs) =<< xs' @@ -55,13 +54,14 @@ simpleExpToResolved funcDefs _ (SimpleIdent a name) = Just func -> Right $ RPartiallyApplied a func [] Nothing -> Left $ FuncNameNotRecognized a name -tryToResolvePartial :: (Semigroup a, Show a) => FData -> Resolved a -> [Resolved a] -> EitherF a (Resolved a) +tryToResolvePartial :: (IsTrace trc) => + FData -> Resolved trc -> [Resolved trc] -> EitherF trc (Resolved trc) tryToResolvePartial fData (RPartiallyApplied a funcDef existingArgs) newArgs | (length allArgs) < (length $ expTypes) = Right $ RPartiallyApplied a funcDef allArgs | (length allArgs) == (length $ expTypes) = let actualArgTypes = mapM getResolvedType allArgs - a' = L.foldl' (<>) a (getTrace <$> newArgs) + a' = L.foldl' (<>) a (getRange <$> newArgs) validated = validateArgs a' fName expTypes <$> actualArgTypes in case validated of Left err -> Left err @@ -105,7 +105,7 @@ convertToBool (RLit a (LBool bl)) = Right $ bl convertToBool x = case getResolvedType x of Left e -> Left e - Right typ -> Left $ Can'tResolveAsBool (getTrace x) (T.pack "placeholder") typ + Right typ -> Left $ Can'tResolveAsBool (getRange x) (T.pack "placeholder") typ getResolvedType :: Resolved a -> EitherF a ResolvedType getResolvedType (RPartiallyApplied a funcDef existingArgs) = diff --git a/app/SimpleExp.hs b/app/SimpleExp.hs index e575758..369a505 100644 --- a/app/SimpleExp.hs +++ b/app/SimpleExp.hs @@ -8,7 +8,7 @@ module SimpleExp import qualified Data.Text as T import ASTShow -import HasTrace +import IsTrace import Lit import RawExp diff --git a/app/SimpleExpFuncs.hs b/app/SimpleExpFuncs.hs index ff9379d..0e1cce7 100644 --- a/app/SimpleExpFuncs.hs +++ b/app/SimpleExpFuncs.hs @@ -7,15 +7,15 @@ import qualified Data.Text as T import ASTShow import Exceptions +import IsTrace import RawExp import RawExpFuncs -import Reproduces import SimpleExp -rawExpToSimpleExp :: (Semigroup a, Reproduces a) => RawExp a -> EitherF a (SimpleExp a) +rawExpToSimpleExp :: IsTrace trc => RawExp trc -> EitherF trc (SimpleExp trc) rawExpToSimpleExp expr = mapRawExpToSimpleExp <$> simplifyRawExp expr -mapRawExpToSimpleExp :: (Semigroup a, Reproduces a) => RawExp a -> SimpleExp a +mapRawExpToSimpleExp :: IsTrace trc => RawExp trc -> SimpleExp trc mapRawExpToSimpleExp (RawApply a xs) = SimpleApply a $ mapRawExpToSimpleExp <$> xs mapRawExpToSimpleExp (RawIdent a name) = SimpleIdent a name diff --git a/app/Trace.hs b/app/Trace.hs new file mode 100644 index 0000000..858ec91 --- /dev/null +++ b/app/Trace.hs @@ -0,0 +1,36 @@ +module Trace ( + Trace(..) + , mkTrace +) where + +import qualified Data.Text as T +import TextShow + +import ASTShow (intercalate) +import IsTrace + +data Trace a = Trace { + focus :: a + , clauses :: [Clause a] +} + +instance (Semigroup a) => Semigroup (Trace a) where + x <> y = Trace ((focus x) <> (focus y)) ((clauses x) ++ (clauses y)) + +data Clause a = + OriginallyDefined a (Trace a) + +mkTrace :: a -> Trace a +mkTrace a = Trace a [] + +getClauseTrace :: IsTrace a => T.Text -> Clause a -> Builder +getClauseTrace origTxt (OriginallyDefined refTrace cTrace) = + "where " <> (trace origTxt refTrace) + <> " is defined here " <> (trace origTxt cTrace) + +instance IsTrace a => IsTrace (Trace a) where + trace origTxt (Trace focus clauses) = + let + clauseBuilders = getClauseTrace origTxt <$> clauses + in (trace origTxt focus) <> "\n" <> (intercalate "\n" clauseBuilders) + diff --git a/app/TreeFilter.hs b/app/TreeFilter.hs index 169786c..ffb6638 100644 --- a/app/TreeFilter.hs +++ b/app/TreeFilter.hs @@ -25,6 +25,7 @@ import Output import Exceptions import ExceptionFuncs import Functions +import IsTrace import Parser (parseTreeSurgeon) import SimpleExp import SimpleExpFuncs @@ -104,7 +105,7 @@ filterTreeWith filterStr tree = do filtered <- filterTreeWith' [] matcher validated return $ fromJust filtered -applyExpression :: (Semigroup a, Show a) => SimpleExp a -> FData -> EitherF a Bool +applyExpression :: IsTrace trc => SimpleExp trc -> FData -> EitherF trc Bool applyExpression expr fData = do resolved <- simpleExpToResolved functions fData expr asBool <- convertToBool resolved @@ -152,7 +153,7 @@ filterStrToSimpleExp :: BS.ByteString -> Either [TSException X.Range] (SimpleExp filterStrToSimpleExp filterStr = let parsed = X.runAlex filterStr parseTreeSurgeon in case parsed of - Left e -> Left [Other Can'tParse] + Left _ -> Left [Other Can'tParse] Right p -> left (\e -> [Filter e]) $ rawExpToSimpleExp p -- simplified = rawExpToSimpleExp =<< parsed' -- in left (\e -> [e]) simplified diff --git a/notes/notes.md b/notes/notes.md index 42b7cc9..3829da4 100644 --- a/notes/notes.md +++ b/notes/notes.md @@ -1,3 +1,71 @@ +2023-11-23 +---------- + +We do *not* want the Exp variables themselves to implement semigroup, because what does it mean to do `LPar <> LList` +Do we even want the Exp variables to implement getTrace? Or do we just want the range variable itself to implement getTrace? +There are two viable options here: + - the range variables implement getTrace, AND ALSO store the clauses etc and other metadata. + - the Exp variables implement getTrace (not semigroup) +We should call the `a` variable `IsTrace`, not `HasTrace`. And that should be the restriction. That's much neater. + +Note that it would probably simplify the type system a bit if we did have a single type, not `Reproduces` and `IsTrace`. +- The difference really is semigroup. But maybe if we had an `addClause` function and also an `append` function that would be OK. +- I mean append is just semigroup there. It applies to focus a + + +Should eg `RawApply` capture the function plus arguments? I think it has to. For one thing, if we did not do that, then in trying to reconstruct the original function call, we'd probably not reconstruct it correctly (eg if it had additional whitespace). + +`Reproduces` - just recreates some text from the original source text. Implements semigroup because it is a single contiguous piece of source code +`IsTrace` - gives a fuller explanation. Does not implement Semigroup because it may take original source from multiple locations. + + +2023-11-22 +---------- + +We have two similar typeclasses which are possibliy the same: +`Reproduces` for re-creating the original text, from a Range +`IsTrace`, for + +`Reproduces` needs to be a Semigroup, I think. Less obvious how to make + +These are probably the same really. + +But `Reproduces` recreates only a range. whereas `IsTrace` recreates a snippet, including its sub-clauses. + +Should `IsTrace` be on the expression rather than the expression? No I don't think so. +What about for, say `RawApply` though? If it's only on the `a` then it feels like we're storing two parallel hierarchies, the hierarchy within the expression, and the hierarchy within the `a`. + +How might that work? +``` +error in endsWith someStr someNum +... where someStr was defined here: let someStr = "foo" +... where someNum was defined here: let someNum = 1 +``` +When printing the trace, we could check if any of the `args` of `RawApply` are outside the Range of the `RawApply` itself. But this feels a bit clumsy. + +When printing the trace, do we want to refer only to `RawApply`s main `a`, or the `a`s of the `args`? +- just doing the former feels a bit clumsy +- but doing the latter requires some more sophisticated logic to see if we need to state where clauses. +- Maybe it would be better to have the `a` as `Maybe a` so that we can eliminate them as they're used up. Or maybe we give `Trace` a kind of null constructor. That's better. +- Maybe `Trace` has `focus` and `additionalClauses` field? + - So you want to print the trace for `RawApply`: + - `RawApply` only stores its own trace, ie literally just to the function name. + - It iterates through its args and `<>`s their `focus` fields to itself, to create + `endsWith someStr someNum` + - Then it iterates again through its args and prints their `additionalClauses`s separately: + `... where someStr was defined here: let someStr = "foo"`. + - This seems neat, but are there any other additional clauses we can think of? + - Perhaps `... where (+ 1) is a partially applied argument expecting an additional argument of type Int`. + - Do we need something like a `define` function? This is probably `errorShow`. + - Do clauses need to be stored, or can they be magicked up on demand? + - Stored, I think. Think of `OriginallyDefined`. + - So we could have a single typeclass for this, it should do `reproduce` as well as semigroup. + - Semigroup for Trace should string together the focus fields, and stack together the additionalClauses. + +Currently RawExp comes out the parser with `a` as X.Range. +We want it to be converted (at some point) to `a` as `Trace X.Range`. We can get rid of `TraceSpan`. +This needs to happen before `deName`, for which we need the whereClauses thing. It should probably happen within the parser. Probably just give everything a simple Trace type. + 2023-11-19 ---------- diff --git a/tree-surgeon.cabal b/tree-surgeon.cabal index f7f94ad..f5bfb5d 100644 --- a/tree-surgeon.cabal +++ b/tree-surgeon.cabal @@ -31,17 +31,17 @@ common deps , text , text-show other-modules: - , Exp , RawExp , Cli + , ExceptionFuncs , Functions , FunctionDefinition + , IsTrace , Lexer , Lit , Output , ParseException , Parser - , Reproduces , Resolved , ResolvedType , TreeFilter