summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYorhel <git@yorhel.nl>2017-10-08 14:35:14 +0200
committerYorhel <git@yorhel.nl>2017-10-08 14:35:14 +0200
commit24329e74d64ecbc2faaf21b72f85475da7ceb54a (patch)
tree7613d3daf43622a53368cdfe0d09de36aa6f8fa7
parent8570bb0d4922c84225daf1506378c47dd1ef53d4 (diff)
Add power and ternary operator
-rw-r--r--Logstat/Eval.hs2
-rw-r--r--Logstat/Parse.hs6
-rw-r--r--Logstat/Types.hs11
-rw-r--r--Tests/Main.hs5
4 files changed, 17 insertions, 7 deletions
diff --git a/Logstat/Eval.hs b/Logstat/Eval.hs
index ffd80e3..7dd8bb8 100644
--- a/Logstat/Eval.hs
+++ b/Logstat/Eval.hs
@@ -35,6 +35,7 @@ evalExpr st expr = case expr of
ELit e -> return e
EField f -> getField st f
ENot e -> bool . not . asBool <$> evalExpr st e
+ EIf e t f-> evalExpr st e >>= \b -> evalExpr st $ if asBool b then t else f
ENeg e -> do
v <- evalExpr st e >>= asNum
@@ -60,6 +61,7 @@ evalExpr st expr = case expr of
OMul -> iop (*)
ODiv -> idiv (/)
OMod -> idiv mod'
+ OPow -> iop (**)
OOr -> with a' return $ \a -> if asBool a then return a else with b' return return
OAnd -> with a' return $ \a -> if asBool a then with b' return return else return a
where
diff --git a/Logstat/Parse.hs b/Logstat/Parse.hs
index 6484948..24ee5cc 100644
--- a/Logstat/Parse.hs
+++ b/Logstat/Parse.hs
@@ -140,9 +140,10 @@ stmts end = concat <$> sepEndBy1 stmt (symbol ";") <* end
<|> between (symbol "(") (symbol ")") expr
expr = makeExprParser term
- [ [ Prefix (foldr1 (.) <$> some (ENot <$ (symbol "!")))
+ [ [ InfixR (EOp OPow <$ symbol "**") ]
+ , [ Prefix (foldr1 (.) <$> some (ENot <$ (symbol "!")))
, Prefix (ENeg <$ symbol "-" ) ]
- , [ InfixL (EOp OMul <$ symbol "*" )
+ , [ InfixL (EOp OMul <$ (lexeme $ try $ char '*' <* notFollowedBy (char '*')))
, InfixL (EOp ODiv <$ symbol "/" )
, InfixL (EOp OMod <$ symbol "%" ) ]
, [ InfixL (EOp OPlus <$ symbol "+" )
@@ -162,6 +163,7 @@ stmts end = concat <$> sepEndBy1 stmt (symbol ";") <* end
, InfixN (EOp OINeq <$ symbol "!=") ]
, [ InfixL (EOp OAnd <$ symbol "&&") ]
, [ InfixL (EOp OOr <$ symbol "||") ]
+ , [ InfixR (try $ between (symbol "?") (symbol ":") expr >>= \m -> return $ (\l r -> EIf l m r)) ]
]
number = lexeme $ try L.float
diff --git a/Logstat/Types.hs b/Logstat/Types.hs
index c835933..7bb3d38 100644
--- a/Logstat/Types.hs
+++ b/Logstat/Types.hs
@@ -67,17 +67,18 @@ instance Ord a => Ord (SortItem a) where (SortItem a _) <= (SortItem b _) = a <=
data Op
- = OEq | ONeq | OLt | OGt | OLe | OGe -- String comparison
- | OIEq | OINeq | OILt | OIGt | OILe | OIGe -- Integer comparison
- | OConcat -- String operations
- | OPlus | OMinus | OMul | ODiv | OMod -- Integer operations
- | OAnd | OOr -- Boolean operations
+ = OEq | ONeq | OLt | OGt | OLe | OGe -- String comparison
+ | OIEq | OINeq | OILt | OIGt | OILe | OIGe -- Integer comparison
+ | OConcat -- String operations
+ | OPlus | OMinus | OMul | ODiv | OMod | OPow -- Integer operations
+ | OAnd | OOr -- Boolean operations
deriving(Eq,Show)
data Expr
= EField !Field
| ELit !Val
| EOp !Op !Expr !Expr
+ | EIf !Expr !Expr !Expr
| ENeg !Expr
| ENot !Expr
deriving(Show)
diff --git a/Tests/Main.hs b/Tests/Main.hs
index 034e50e..2387c27 100644
--- a/Tests/Main.hs
+++ b/Tests/Main.hs
@@ -48,4 +48,9 @@ main = runTestTT $ test
, expr "0 || \"abc\"" "abc"
, expr "0 && \"abc\"" "0"
, expr "1 && \"abc\"" "abc"
+ , expr "2 ** 16" "65536"
+ , expr "1 ? 2 : 3" "2"
+ , expr "0 ? 1 : 2" "2"
+ , expr "0 ? 1 : 2 ? 3 : 4" "3"
+ , expr "1 + 2 * 3 == 7 ? (1?4:5) : 6" "4"
]