Limited by the number of highlighted functions?
m-rph opened this issue · 5 comments
Hi, thanks for the great work!
I am having an issue where, in some files with many small functions highlighting just stops working.
Hi there, thanks for the bug report.
Could you give an example which causes problems? Hard to know what's the problem might be otherwise, as I haven't run this behaviour I don't think.
I don't really have a minimal example, but this is a file that causes said issue. But you can't really compile it because it is missing the rest of the definitions...
Paradoxically, highlighting also stops working in Github.
module ExtendedOperators where
import Control.Monad ( (>=>) )
import BoaAST
( Op(..), Value(FalseVal, IntVal, ListVal, StringVal, TrueVal) )
import Utils ( showOperatorSign, showValueConstrName )
alwaysSuccess :: (t1 -> t2 -> b) -> (t1, t2) -> Either a b
alwaysSuccess op (a, b) = Right $ op a b
-- Commutative Operators
addE :: (Int, Int) -> Either a Value
addE = alwaysSuccess (+) >=> Right . IntVal
subE :: (Int, Int) -> Either a Value
subE = alwaysSuccess (-) >=> Right . IntVal
mulE :: (Int, Int) -> Either a Value
mulE = alwaysSuccess (*) >=> Right . IntVal
divE :: (Int, Int) -> Either String Value
divE (a,0) = Left "Division by 0"
divE (a,b) = Right . IntVal $ a `div` b
modE :: (Int, Int) -> Either String Value
modE (a,0) = Left "Modulo 0"
modE (a,b) = Right . IntVal $ a `mod` b
eqE :: Eq a1 => (a1, a1) -> Either String Value
eqE = alwaysSuccess (==) >=> Right . boolToBoolVal
ltE :: Ord a => (a, a) -> Either String Value
ltE = alwaysSuccess (<) >=> Right . boolToBoolVal
gtE :: Ord a => (a, a) -> Either String Value
gtE = alwaysSuccess (>) >=> Right . boolToBoolVal
strAddE :: (String, String) -> Either String Value
strAddE = alwaysSuccess (++) >=> Right . StringVal
listAddE :: ([Value], [Value]) -> Either String Value
listAddE = alwaysSuccess (++) >=> Right . ListVal
-- Taken from user1812457 at https://stackoverflow.com/questions/30588221
substring :: String -> String -> Bool
substring (_:_) [] = False
substring xs ys
| prefix xs ys = True
| substring xs (tail ys) = True
| otherwise = False
prefix :: String -> String -> Bool
prefix [] _ = True
prefix (_:_) [] = False
prefix (x:xs) (y:ys) = (x == y) && prefix xs ys
evaluateToIIOperator :: Op -> [(Int, Int) -> Either String Value]
evaluateToIIOperator Plus = [addE]
evaluateToIIOperator Minus = [subE]
evaluateToIIOperator Times = [mulE]
evaluateToIIOperator Div = [divE]
evaluateToIIOperator Mod = [modE]
evaluateToIIOperator Less = [ltE]
evaluateToIIOperator Greater = [gtE]
evaluateToIIOperator _ = []
evaluateOrdLLOperator :: Op -> [([Value], [Value]) -> Either String Value]
evaluateOrdLLOperator operator = let
reduction :: Either String Value -> Either String Value -> Either String Value
reduction accumulated current = accumulated >>= (\f ->
let in case (f, current) of
(TrueVal, cr) -> cr -- True && a = a
(_, err@(Left _)) -> err
(_, _) -> Right FalseVal
)
a = \(a,b)-> let
individualElements = zipWith (operate operator) a b
in foldl reduction (Right TrueVal) individualElements
in [a]
evaluateToLLOperator :: Op -> [([Value], [Value]) -> Either String Value]
evaluateToLLOperator Plus = [\(a, b) -> Right . ListVal $ a ++ b]
evaluateToLLOperator Less = evaluateOrdLLOperator Less
evaluateToLLOperator Greater = evaluateOrdLLOperator Greater
evaluateToLLOperator _ = []
evaluateToALOperator :: Op -> [(Value, [Value]) ->Either String Value]
evaluateToALOperator In = [\(v,l) -> Right . boolToBoolVal $ v`elem`l]
evaluateToALOperator _ = []
evaluateToILOperator :: (Num t, Enum t) => Op -> [(t, [Value]) -> Either a Value]
evaluateToILOperator Times = [\(a, b) -> Right . ListVal $ [v| _ <- [1..a], v<-b]]
evaluateToILOperator _ = []
evaluateToSSOperator :: Op -> [(String, String) -> Either String Value]
evaluateToSSOperator Plus = [strAddE]
evaluateToSSOperator Less = [ltE]
evaluateToSSOperator Greater = [gtE]
evaluateToSSOperator In = [\(left,right) -> Right . boolToBoolVal $ substring left right]
evaluateToSSOperator _ = []
evaluateToSIOperator :: Op -> [(Int,String) -> Either String Value]
evaluateToSIOperator Times = [\(a,b) -> Right . StringVal $ [c|i<-[0..a], c<-b]]
evaluateToSIOperator _ = []
evaluateToEqOperator :: Eq a1 => Op -> [(a1, a1) -> Either String Value]
evaluateToEqOperator Eq = [eqE]
evaluateToEqOperator _ = []
evaluateToInt :: Value -> [Int]
evaluateToInt TrueVal = [1]
evaluateToInt FalseVal = [0]
evaluateToInt (IntVal v) = [v]
evaluateToInt _ = []
evaluateToList :: Value -> [[Value]]
evaluateToList (ListVal l) = [l]
evaluateToList _ = []
evaluateToString :: Value -> [String]
evaluateToString (StringVal s) = [s]
evaluateToString _ = []
boolToBoolVal :: Bool -> Value
boolToBoolVal True = TrueVal
boolToBoolVal False = FalseVal
applyFtoCartesian :: [a1] -> [b] -> ((a1, b) -> a2) -> [a2]
applyFtoCartesian xs ys f = [f (x, y) | x <- xs, y <- ys]
operate :: Op -> Value -> Value -> Either [Char] Value
operate op x y =
case results of
[] ->
Left $
"unsupported operand type(s) for "
++ showOperatorSign op
++ ": '"
++ showValueConstrName x
++ "' and '"
++ showValueConstrName y
++ "'"
(r : _) -> r
where
numXs = [x] >>= evaluateToInt
numYs = [y] >>= evaluateToInt
-- num x num operations
numericResults = [op] >>= evaluateToIIOperator >>= applyFtoCartesian numXs numYs
listXs = [x] >>= evaluateToList
listYs = [y] >>= evaluateToList
-- operations on lists
listResults = [op] >>= evaluateToLLOperator >>= applyFtoCartesian listXs listYs
stringXs = [x] >>= evaluateToString
stringYs = [y] >>= evaluateToString
-- operations on strings
stringResults = [op] >>= evaluateToSSOperator >>= applyFtoCartesian stringXs stringYs
ilOperators = [op] >>= evaluateToILOperator
-- int list and list int operations, all commutative,
-- so we check both sides.
ilResults = ilOperators >>= applyFtoCartesian numXs listYs
ilResults2 = ilOperators >>= applyFtoCartesian numYs listXs
siOperators = [op] >>= evaluateToSIOperator
-- int string / string int operations, all commutative
-- we trivially check both sides
strIntResults = siOperators >>= applyFtoCartesian numXs stringYs
strIntResults2 = siOperators >>= applyFtoCartesian numYs stringXs
-- equality check
eqResults = [op] >>= evaluateToEqOperator >>= applyFtoCartesian [x] [y]
-- x in someList
alResults = [op] >>= evaluateToALOperator >>= applyFtoCartesian [x] listYs
results = numericResults
++ listResults
++ stringResults
++ ilResults
++ ilResults2
++ strIntResults
++ strIntResults2
++ alResults
++ eqResults
If I comment out this part:
evaluateToILOperator :: (Num t, Enum t) => Op -> [(t, [Value]) -> Either a Value]
evaluateToILOperator Times = [\(a, b) -> Right . ListVal $ [v| _ <- [1..a], v<-b]]
evaluateToILOperator _ = []
It makes the following two functions to highlight.
Right, yeah, the problem is that
[v| _ <- [1..a], v<-b]]
is parsed as a quasi-quotation and not as a list comprehension. Unfortunately that's kind of by design as the syntax is inherently ambiguous. So you need to add a space, e.g.
[ v | _ <- [1..a], v<-b]]
Oh, okay, that makes a lot of sense! Thanks and sorry for the false positive ^^'.
Feel free to close this :)
Ah right ... yeah that makes sense. It is so unfortunate, but the vscode parser implementations don't allow us to recognize language extensions.