aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJuan J. Martinez <jjm@usebox.net>2022-09-06 22:53:08 +0100
committerJuan J. Martinez <jjm@usebox.net>2022-09-06 22:53:08 +0100
commitcd9bd7decd25301a6da01fd97feed1cc33cfabbf (patch)
tree2b439efc7e4be565d0fde0838e34c87c5d90e8a6
parentd08042be1e0ae158f124bb6848f5843a804a6544 (diff)
downloadmicro-lang-hs-cd9bd7decd25301a6da01fd97feed1cc33cfabbf.tar.gz
micro-lang-hs-cd9bd7decd25301a6da01fd97feed1cc33cfabbf.zip
Typecheck binary operator
-rw-r--r--src/Compiler.hs32
-rw-r--r--test/Language.hs11
2 files changed, 28 insertions, 15 deletions
diff --git a/src/Compiler.hs b/src/Compiler.hs
index ce68c16..2a836ee 100644
--- a/src/Compiler.hs
+++ b/src/Compiler.hs
@@ -81,6 +81,19 @@ typecheckReturn Nothing Nothing = return $ Nothing
typecheckReturn Nothing fret = return $ Just $ "invalid return value\n found: ()\n expected: " ++ showMaybet fret
typecheckReturn (Just value) fret = typecheckVal value fret
+-- | @typecheckBinOp a b pos@ resolves @a@ (left) and compares it to the type
+-- of @b@ via typecheckVal.
+typecheckBinOp :: A.Expr -> A.Expr -> SourcePos -> State CompState CompResult
+typecheckBinOp a b pos = do
+ l <- compile a
+ case l of
+ Right tl -> do
+ tr <- typecheckVal b $ tl
+ case tr of
+ Just err -> addError $ Error TypeError err pos
+ Nothing -> return $ Right $ tl
+ _ -> return $ Right Nothing -- error resolving left
+
-- built-in types
types = ["bool", "u8", "s8", "u16", "s16"]
@@ -110,21 +123,12 @@ compile x = do
(A.Module name pos) -> return $ Right Nothing
(A.Num _ _) -> return $ Right $ Just $ A.Type "u8" -- TODO: placeholder
(A.Bool' _ _) -> return $ Right $ Just $ A.Type "bool"
- (A.BinOp A.Assign pos a@(A.Variable _ _) b) -> do
- l <- compile a
- case l of
- Right tl -> do
- tr <- typecheckVal b $ tl
- case tr of
- Just err -> addError $ Error TypeError err pos
- Nothing -> return $ Right $ tl
- _ -> return $ Right Nothing -- error resolving left
- (A.BinOp A.Assign pos _ _) ->
+ (A.BinOp A.Assign pos a@(A.Variable _ _) b) ->
+ typecheckBinOp a b pos
+ (A.BinOp A.Assign pos _ b) ->
addError $ Error InvalidTarget "invalid assignment target" pos
- (A.BinOp _ _ a b) -> do
- l <- compile a
- r <- compile b
- return $ l -- TODO: placeholder
+ (A.BinOp op pos a b) ->
+ typecheckBinOp a b pos
(A.Func ident params ret body priv anon pos) -> do
-- current env
(ev, errs) <- get
diff --git a/test/Language.hs b/test/Language.hs
index 0b7d6ac..2347b0e 100644
--- a/test/Language.hs
+++ b/test/Language.hs
@@ -379,6 +379,14 @@ testCaseE16 =
\a = false;"
E.TypeError
+testCaseE17 =
+ TestLabel "type mismatch in binary operator" $
+ TestCase $
+ expectError
+ "module main\n\
+ \1 + false;\n"
+ E.TypeError
+
language =
[ testCase2,
testCase3,
@@ -412,5 +420,6 @@ language =
testCaseE13,
testCaseE14,
testCaseE15,
- testCaseE16
+ testCaseE16,
+ testCaseE17
]