aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJuan J. Martinez <jjm@usebox.net>2022-09-06 22:22:32 +0100
committerJuan J. Martinez <jjm@usebox.net>2022-09-06 22:22:32 +0100
commitd08042be1e0ae158f124bb6848f5843a804a6544 (patch)
tree71ffa63234c13f3bf7d31fe3c0a3876839cae2e8
parentf8dfbfc1604aea626a6502b9f6d06ea1299a0cdb (diff)
downloadmicro-lang-hs-d08042be1e0ae158f124bb6848f5843a804a6544.tar.gz
micro-lang-hs-d08042be1e0ae158f124bb6848f5843a804a6544.zip
Assignation
-rw-r--r--src/Ast.hs5
-rw-r--r--src/Compiler.hs13
-rw-r--r--src/Error.hs3
-rw-r--r--src/Parser.hs12
-rw-r--r--test/Language.hs35
5 files changed, 61 insertions, 7 deletions
diff --git a/src/Ast.hs b/src/Ast.hs
index 075b9f8..4f4a2f9 100644
--- a/src/Ast.hs
+++ b/src/Ast.hs
@@ -22,7 +22,7 @@ type FuncParam = (Ident, Type, Bool, SourcePos)
data Expr
= Num Integer SourcePos
| Bool' Bool SourcePos
- | BinOp Op Expr Expr
+ | BinOp Op SourcePos Expr Expr
| Variable Ident SourcePos
| -- v type value private pos
Var Ident Type Expr Bool SourcePos
@@ -34,7 +34,8 @@ data Expr
deriving (Eq, Ord, Show)
data Op
- = Plus
+ = Assign
+ | Plus
| Minus
| Mul
| Div
diff --git a/src/Compiler.hs b/src/Compiler.hs
index 38b5227..ce68c16 100644
--- a/src/Compiler.hs
+++ b/src/Compiler.hs
@@ -110,7 +110,18 @@ 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 b) -> do
+ (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 _ _) ->
+ addError $ Error InvalidTarget "invalid assignment target" pos
+ (A.BinOp _ _ a b) -> do
l <- compile a
r <- compile b
return $ l -- TODO: placeholder
diff --git a/src/Error.hs b/src/Error.hs
index 9aad85d..d128d32 100644
--- a/src/Error.hs
+++ b/src/Error.hs
@@ -4,7 +4,7 @@ import Data.List (sort)
import Text.Parsec (SourcePos, errorPos)
import Text.Parsec.Error (ParseError, errorMessages, showErrorMessages)
-data ErrorType = GenericError | TypeError | UnexpectedReturn | AlreadyDefined | NonCallable | Undefined | UndefinedType deriving (Show)
+data ErrorType = GenericError | TypeError | UnexpectedReturn | AlreadyDefined | NonCallable | Undefined | UndefinedType | InvalidTarget deriving (Show)
instance Enum ErrorType where
fromEnum GenericError = 0
@@ -14,6 +14,7 @@ instance Enum ErrorType where
fromEnum NonCallable = 4
fromEnum Undefined = 5
fromEnum UndefinedType = 6
+ fromEnum InvalidTarget = 7
toEnum _ = error "toEnum is undefined for Error"
data Error = Error ErrorType String SourcePos
diff --git a/src/Parser.hs b/src/Parser.hs
index 5ee6de9..12f04d9 100644
--- a/src/Parser.hs
+++ b/src/Parser.hs
@@ -7,10 +7,18 @@ import Text.Parsec
import qualified Text.Parsec.Expr as E
import Text.Parsec.String (Parser)
-binary s f assoc = E.Infix (reservedOp s >> return (BinOp f)) assoc
+binary s f assoc =
+ E.Infix
+ ( reservedOp s
+ >> do
+ pos <- getPosition
+ return $ BinOp f pos
+ )
+ assoc
opTable =
- [ [ binary "*" Mul E.AssocLeft,
+ [ [binary "=" Assign E.AssocLeft],
+ [ binary "*" Mul E.AssocLeft,
binary "/" Div E.AssocLeft
],
[ binary "+" Plus E.AssocLeft,
diff --git a/test/Language.hs b/test/Language.hs
index 5c1bb57..0b7d6ac 100644
--- a/test/Language.hs
+++ b/test/Language.hs
@@ -228,6 +228,18 @@ testCase16 =
A.Var "b" (A.Type "bool") (A.Bool' True $ newPos "test" 3 11) True $ newPos "test" 3 1
]
+testCase17 =
+ TestLabel "parse assignation" $
+ TestCase $
+ assertAst
+ "module main\n\
+ \var a: u8 = 0;\n\
+ \a = 10;"
+ [ A.Module "main" $ newPos "test" 1 1,
+ A.Var "a" (A.Type "u8") (A.Num 0 $ newPos "test" 2 13) False $ newPos "test" 2 5,
+ A.BinOp A.Assign (newPos "test" 3 5) (A.Variable "a" $ newPos "test" 3 1) (A.Num 10 $ newPos "test" 3 5)
+ ]
+
-- test errors
testCaseE1 =
@@ -349,6 +361,24 @@ testCaseE14 =
\var a: bool = (a:u8): u8 { return a; };\n"
E.TypeError
+testCaseE15 =
+ TestLabel "invalid assignation target" $
+ TestCase $
+ expectError
+ "module main\n\
+ \def fn() { return; }\n\
+ \fn() = 10;"
+ E.InvalidTarget
+
+testCaseE16 =
+ TestLabel "type mismatch in assignation" $
+ TestCase $
+ expectError
+ "module main\n\
+ \var a: u8 = 0;\n\
+ \a = false;"
+ E.TypeError
+
language =
[ testCase2,
testCase3,
@@ -365,6 +395,7 @@ language =
testCase14,
testCase15,
testCase16,
+ testCase17,
-- errors
testCaseE1,
testCaseE2,
@@ -379,5 +410,7 @@ language =
testCaseE11,
testCaseE12,
testCaseE13,
- testCaseE14
+ testCaseE14,
+ testCaseE15,
+ testCaseE16
]