Skip to content

Commit 755e47e

Browse files
committed
[feat:treewide] add comparison operators
1 parent 51ecdc7 commit 755e47e

File tree

5 files changed

+58
-23
lines changed

5 files changed

+58
-23
lines changed

src/Evaluator/Evaluator.hs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ evaluateExpression gd ld (Unary op expr) =
2424
analyseUnaryOp op expr
2525
-- replace with the result of function call
2626
evaluateExpression gd ld (FunctionCall name argExprs) =
27-
evaluateFunctionCall gd ld name evaluateExpression argExprs evalNative
27+
evaluateFunctionCall gd ld name evaluateExpression argExprs (curry evalNative)
2828
-- replace with the if-true (ift) or if-false (iff) expr
2929
evaluateExpression gd ld (Conditional cond ift iff) = do
3030
evaluateExpression gd ld cond >>= \case

src/Evaluator/NativeFns.hs

Lines changed: 40 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -38,21 +38,43 @@ getStr x = case x of
3838
FunctionDef txt vdt x1 exs b -> "nil"
3939
y -> error $ "could not get string from " <> show y
4040

41-
evalNative :: T.Text -> VDataType -> [Expr] -> IO Expr
42-
evalNative "+i" Int args = pure $ IntLiteral $ round (sum (map getNumber args))
43-
evalNative "+f" Float args = pure $ FloatLiteral (sum (map getNumber args))
44-
evalNative "-i" Int args = pure $ IntLiteral $ round (foldl1 (-) (map getNumber args))
45-
evalNative "-f" Float args = pure $ FloatLiteral (foldl1 (-) (map getNumber args))
46-
evalNative "*i" Int args = pure $ IntLiteral $ round (product (map getNumber args))
47-
evalNative "*f" Float args = pure $ FloatLiteral (product (map getNumber args))
48-
evalNative "/i" Int args = pure $ IntLiteral $ round (foldl1 (/) (map getNumber args))
49-
evalNative "/f" Float args = pure $ FloatLiteral (foldl1 (/) (map getNumber args))
50-
evalNative "str" String args = pure $ StrLiteral (foldl1 (<>) (map getStr args))
51-
evalNative "print" NilType args = (putStrLn . T.unpack) (foldl1 (<>) (map getStr args)) >> pure Nil
52-
evalNative ">" Bool exprs =
53-
if length exprs == 2
54-
then case (head exprs, exprs !! 1) of
55-
(IntLiteral iv, IntLiteral iv') -> pure $ BoolLiteral (iv > iv')
56-
_ -> undefined -- TODO
57-
else error "can only equality check two arguments"
58-
evalNative name _ _ = error $ "evaluator does not know how to execute the native function '" <> T.unpack name <> "'"
41+
evalNative :: (T.Text, VDataType) -> [Expr] -> IO Expr
42+
evalNative nt args
43+
| nt == ("+i", Int) = pure $ IntLiteral $ round (sum (map getNumber args))
44+
| nt == ("+f", Float) = pure $ FloatLiteral (sum (map getNumber args))
45+
| nt == ("-i", Int) = pure $ IntLiteral $ round (foldl1 (-) (map getNumber args))
46+
| nt == ("-f", Float) = pure $ FloatLiteral (foldl1 (-) (map getNumber args))
47+
| nt == ("*i", Int) = pure $ IntLiteral $ round (product (map getNumber args))
48+
| nt == ("*f", Float) = pure $ FloatLiteral (product (map getNumber args))
49+
| nt == ("/i", Int) = pure $ IntLiteral $ round (foldl1 (/) (map getNumber args))
50+
| nt == ("/f", Float) = pure $ FloatLiteral (foldl1 (/) (map getNumber args))
51+
| nt == ("str", String) = pure $ StrLiteral (foldl1 (<>) (map getStr args))
52+
| nt == ("print", NilType) = (putStrLn . T.unpack) (foldl1 (<>) (map getStr args)) >> pure Nil
53+
| nt == (">", Bool)
54+
|| nt == (">=", Bool)
55+
|| nt == ("<", Bool)
56+
|| nt == ("<=", Bool)
57+
|| nt == ("/=", Bool)
58+
|| nt == ("==", Bool) =
59+
if length args == 2
60+
then case (head args, args !! 1) of
61+
(IntLiteral iv, IntLiteral iv') ->
62+
pure $
63+
BoolLiteral
64+
( ( case fst nt of
65+
">" -> (>)
66+
">=" -> (>=)
67+
"<" -> (<)
68+
"<=" -> (<=)
69+
"==" -> (==)
70+
"!=" -> (/=)
71+
)
72+
iv
73+
iv'
74+
)
75+
(FloatLiteral iv, IntLiteral iv') -> pure $ BoolLiteral (iv > fromIntegral iv')
76+
(IntLiteral iv, FloatLiteral iv') -> pure $ BoolLiteral (fromIntegral iv > iv')
77+
(FloatLiteral iv, FloatLiteral iv') -> pure $ BoolLiteral (iv > iv')
78+
(x, y) -> error $ "Can't compare " <> show x <> " with " <> show y
79+
else error "can only equality check two arguments"
80+
| otherwise = error $ "evaluator does not know how to execute the native function '" <> T.unpack (fst nt) <> "'"

src/Main.hs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ import Transpiler.Backends.JS.JS (jsBackend, jsStdlib)
3636
import Transpiler.Transpiler (transpile)
3737

3838
axlStdlib :: T.Text
39-
axlStdlib = B.decodeUtf8 $(embedFile "stdlib/stdlib.axl")
39+
axlStdlib = "nil\n" <> B.decodeUtf8 $(embedFile "stdlib/stdlib.axl")
4040

4141
makeNativeFunction :: VDataType -> Def
4242
makeNativeFunction ret = AU.Function ret ([("args", Any)], True) [] True

src/Parser/Combinators.hs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import Data.Text as T (Text, pack, unpack)
99
import qualified Data.Text as T
1010
import Data.Void (Void)
1111
import Parser.Ast
12-
( VDataType (ArrayOf, Bool, Float, Inferred, Int, NilType, String, Any),
12+
( VDataType (Any, ArrayOf, Bool, Float, Inferred, Int, NilType, String),
1313
)
1414
import Text.Megaparsec
1515
( MonadParsec (notFollowedBy, observing, takeWhileP, try),
@@ -102,12 +102,12 @@ rword :: String -> Parser ()
102102
rword w = (lexeme . try) (string (pack w) *> notFollowedBy alphaNumChar)
103103

104104
mathSymbol :: Parser Char
105-
mathSymbol = single '+' <|> single '-' <|> single '/' <|> single '%' <|> single '*' <|> single '>'
105+
mathSymbol = single '+' <|> single '-' <|> single '/' <|> single '%' <|> single '*' <|> single '>' <|> single '<' <|> single '=' <|> single '!'
106106

107107
identifier :: Parser Text
108108
identifier = (lexeme . try) (p <&> pack)
109109
where
110-
p = (:) <$> (letterChar <|> mathSymbol) <*> many (alphaNumChar <|> single '-' <|> single '?' <|> single '_')
110+
p = (:) <$> (letterChar <|> mathSymbol) <*> many (alphaNumChar <|> single '-' <|> single '?' <|> single '_' <|> single '=')
111111

112112
getTypeFromStr :: Text -> Parser VDataType
113113
getTypeFromStr "string" = pure String

stdlib/stdlib.axl

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,27 @@
1+
; addition
12
(native defun (+i: int) [&(args: int)])
23
(native defun (+f: float) [&(args: any)])
34

5+
; subtraction
46
(native defun (-i: int) [&(args: int)])
57
(native defun (-f: float) [&(args: any)])
68

9+
; multiplication
710
(native defun (*i: int) [&(args: int)])
811
(native defun (*f: float) [&(args: any)])
912

13+
; division
1014
(native defun (/i: int) [&(args: int)])
1115
(native defun (/f: float) [&(args: any)])
1216

17+
; utility
1318
(native defun (print: nil) [&(args: any)])
1419
(native defun (str: string) [&(args: any)])
20+
21+
; comparison
22+
(native defun (>: bool) [(a: int) (b: int)])
23+
(native defun (>=: bool) [(a: int) (b: int)])
24+
(native defun (<: bool) [(a: int) (b: int)])
25+
(native defun (<=: bool) [(a: int) (b: int)])
26+
(native defun (==: bool) [(a: int) (b: int)])
27+
(native defun (!=: bool) [(a: int) (b: int)])

0 commit comments

Comments
 (0)