diff --git a/src/Dreamberd/Parsing/Elements/Variable.hs b/src/Dreamberd/Parsing/Elements/Variable.hs index 4675dba2..a493b195 100644 --- a/src/Dreamberd/Parsing/Elements/Variable.hs +++ b/src/Dreamberd/Parsing/Elements/Variable.hs @@ -2,8 +2,7 @@ module Dreamberd.Parsing.Elements.Variable (parseVar) where -import Data.Char (isSpace) -import Dreamberd.Parsing.Utils (extractValueAndRest, getVariableName) +import Dreamberd.Parsing.Utils (extractValueAndRest, getVariableName, trimSpaces) import Dreamberd.Parsing.Values (parseAnyValue, parseBool, parseFunctionCall, parseNumber, parseString) import Dreamberd.Types (AstNode (AssignVariable, Identifier, Operator)) @@ -33,12 +32,15 @@ parseVar varType code ast = else let (variableName, drop 1 -> afterEqual) = break (== '=') code - strippedName = filter (not . isSpace) variableName + strippedName = trimSpaces variableName in - getVariableName strippedName >>= \name -> - let - (value, restOfCode) = extractValueAndRest afterEqual - in - parseVarValue varType value >>= \node -> case varType of - Just vt -> Right (restOfCode, ast ++ [AssignVariable vt name node]) - Nothing -> Right (restOfCode, ast ++ [Operator "=" (Identifier name) node]) + if length (words strippedName) > 1 + then Left ("Invalid variable type '" ++ head (words strippedName) ++ "'") + else + getVariableName strippedName >>= \name -> + let + (value, restOfCode) = extractValueAndRest afterEqual + in + parseVarValue varType value >>= \node -> case varType of + Just vt -> Right (restOfCode, ast ++ [AssignVariable vt name node]) + Nothing -> Right (restOfCode, ast ++ [Operator "=" (Identifier name) node]) diff --git a/src/Dreamberd/Parsing/Utils.hs b/src/Dreamberd/Parsing/Utils.hs index b9748d13..78d8b9be 100644 --- a/src/Dreamberd/Parsing/Utils.hs +++ b/src/Dreamberd/Parsing/Utils.hs @@ -1,6 +1,7 @@ -module Dreamberd.Parsing.Utils (getVariableName, extractValueAndRest, parseScope) where +module Dreamberd.Parsing.Utils (getVariableName, extractValueAndRest, parseScope, trimSpaces) where import Data.Char (isSpace) +import Data.List (dropWhileEnd) import Text.Regex.Posix ((=~)) bannedVariables :: [String] @@ -43,3 +44,6 @@ parseScope code = >>= \validCode -> let (scope, rest) = extractScopeAndRest validCode 0 [] in Right (drop 1 scope, rest) + +trimSpaces :: String -> String +trimSpaces = dropWhileEnd isSpace . dropWhile isSpace diff --git a/test/Unit/Dreamberd/TestDreamberdParsing.hs b/test/Unit/Dreamberd/TestDreamberdParsing.hs index 14189377..c2b0bc3d 100644 --- a/test/Unit/Dreamberd/TestDreamberdParsing.hs +++ b/test/Unit/Dreamberd/TestDreamberdParsing.hs @@ -39,6 +39,8 @@ testParseCondition :: Test testParseCondition = TestList [ TestCase (assertEqual "parseCondition basic" (Right ("", [If (Boolean True) [Return (Number 1)] []])) (parseCondition " (true) {return 1;}" [])) + , TestCase (assertEqual "parseCondition wrong without scope" (Left "Scope must start with open bracket but empty code found") (parseCondition " (true)" [])) + , TestCase (assertEqual "parseCondition wrong without scope but other char" (Left "Code must start with an open bracket but starts with 'a'") (parseCondition " (true) anything" [])) , TestCase (assertEqual "parseCondition wrong if without condition" (Left "Missing condition in if statement") (parseCondition "( ) {return 1;}" [])) , TestCase (assertEqual "parseCondition wrong if with broken close condition parenthesis" (Left "If condition must start with '(' and end with ')'") (parseCondition " ) {return 1;}" [])) , TestCase (assertEqual "parseCondition wrong if with broken open condition parenthesis" (Left "If condition must start with '(' and end with ')'") (parseCondition " ( {return 1;}" [])) @@ -60,4 +62,5 @@ testParseDreamberd = , TestCase (assertEqual "parseDreamberd empty code" (Right []) (parseDreamberd " " [])) , TestCase (assertEqual "parseDreamberd invalid variable name" (Left "No variable name found") (parseDreamberd "int * = 4;" [])) , TestCase (assertEqual "parseDreamberd basic loop" (Right [Loop (Boolean True) [AssignVariable "int" "b" (Number 42)] Nothing Nothing]) (parseDreamberd "while (true) {int b = 42;}" [])) + , TestCase (assertEqual "parseDreamberd wrong var type" (Left "Unrecognized element") (parseDreamberd "fluid variable = 89;" [])) ]