diff options
author | Juan J. Martinez <jjm@usebox.net> | 2022-09-06 22:53:08 +0100 |
---|---|---|
committer | Juan J. Martinez <jjm@usebox.net> | 2022-09-06 22:53:08 +0100 |
commit | cd9bd7decd25301a6da01fd97feed1cc33cfabbf (patch) | |
tree | 2b439efc7e4be565d0fde0838e34c87c5d90e8a6 | |
parent | d08042be1e0ae158f124bb6848f5843a804a6544 (diff) | |
download | micro-lang-hs-cd9bd7decd25301a6da01fd97feed1cc33cfabbf.tar.gz micro-lang-hs-cd9bd7decd25301a6da01fd97feed1cc33cfabbf.zip |
Typecheck binary operator
-rw-r--r-- | src/Compiler.hs | 32 | ||||
-rw-r--r-- | test/Language.hs | 11 |
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 ] |