diff --git a/Test/TestParser.hs b/Test/TestParser.hs index ba54821..873f438 100644 --- a/Test/TestParser.hs +++ b/Test/TestParser.hs @@ -144,6 +144,32 @@ testExpressionPreIncrement = TestCase $ testExpressionPreDecrement = TestCase $ assertEqual "expect PreIncrement" (UnaryOperation PreDecrement (Reference "a")) $ parseExpression [DECREMENT,IDENTIFIER "a"] +testExpressionAssign = TestCase $ + assertEqual "expect assign 5 to a" (StatementExpressionExpression (Assignment (Reference "a") (IntegerLiteral 5))) $ + parseExpression [IDENTIFIER "a",ASSIGN,INTEGERLITERAL 5] +testExpressionTimesEqual = TestCase $ + assertEqual "expect assign and multiplication" (StatementExpressionExpression (Assignment (Reference "a") (BinaryOperation Multiplication (Reference "a") (IntegerLiteral 5)))) $ + parseExpression [IDENTIFIER "a",TIMESEQUAL,INTEGERLITERAL 5] +testExpressionDivideEqual = TestCase $ + assertEqual "expect assign and division" (StatementExpressionExpression (Assignment (Reference "a") (BinaryOperation Division (Reference "a") (IntegerLiteral 5)))) $ + parseExpression [IDENTIFIER "a",DIVEQUAL,INTEGERLITERAL 5] +testExpressionPlusEqual = TestCase $ + assertEqual "expect assign and addition" (StatementExpressionExpression (Assignment (Reference "a") (BinaryOperation Addition (Reference "a") (IntegerLiteral 5)))) $ + parseExpression [IDENTIFIER "a",PLUSEQUAL,INTEGERLITERAL 5] +testExpressionMinusEqual = TestCase $ + assertEqual "expect assign and subtraction" (StatementExpressionExpression (Assignment (Reference "a") (BinaryOperation Subtraction (Reference "a") (IntegerLiteral 5)))) $ + parseExpression [IDENTIFIER "a",MINUSEQUAL,INTEGERLITERAL 5] + +testStatementIfThen = TestCase $ + assertEqual "expect empty ifthen" [If (Reference "a") (Block [Block []]) Nothing] $ + parseStatement [IF,LBRACE,IDENTIFIER "a",RBRACE,LBRACKET,RBRACKET] +testStatementIfThenElse = TestCase $ + assertEqual "expect empty ifthen" [If (Reference "a") (Block [Block []]) (Just (Block [Block []]))] $ + parseStatement [IF,LBRACE,IDENTIFIER "a",RBRACE,LBRACKET,RBRACKET,ELSE,LBRACKET,RBRACKET] +testStatementWhile = TestCase $ + assertEqual "expect while" [While (Reference "a") (Block [Block []])] $ + parseStatement [WHILE,LBRACE,IDENTIFIER "a",RBRACE,LBRACKET,RBRACKET] + tests = TestList [ @@ -185,5 +211,14 @@ tests = TestList [ testExpressionPostIncrement, testExpressionPostDecrement, testExpressionPreIncrement, - testExpressionPreDecrement + testExpressionPreDecrement, + testExpressionAssign, + testExpressionTimesEqual, + testExpressionTimesEqual, + testExpressionDivideEqual, + testExpressionPlusEqual, + testExpressionMinusEqual, + testStatementIfThen, + testStatementIfThenElse, + testStatementWhile ] \ No newline at end of file diff --git a/src/Parser/JavaParser.y b/src/Parser/JavaParser.y index e51afb4..4e66850 100644 --- a/src/Parser/JavaParser.y +++ b/src/Parser/JavaParser.y @@ -82,7 +82,7 @@ compilationunit : typedeclarations { $1 } typedeclarations : typedeclaration { [$1] } | typedeclarations typedeclaration { $1 ++ [$2] } -name : simplename { $1 } +name : simplename { Reference $1 } -- | qualifiedname { } typedeclaration : classdeclaration { $1 } @@ -122,7 +122,7 @@ classtype : classorinterfacetype{ } classbodydeclaration : classmemberdeclaration { $1 } | constructordeclaration { $1 } -classorinterfacetype : name { $1 } +classorinterfacetype : simplename { $1 } classmemberdeclaration : fielddeclaration { $1 } | methoddeclaration { $1 } @@ -184,7 +184,7 @@ referencetype : classorinterfacetype { $1 } variabledeclarator : variabledeclaratorid { Declarator $1 Nothing } | variabledeclaratorid ASSIGN variableinitializer { Declarator $1 (Just $3) } -blockstatement : localvariabledeclarationstatement { $1 } +blockstatement : localvariabledeclarationstatement { $1 } -- expected type statement | statement { $1 } formalparameter : type variabledeclaratorid { ParameterDeclaration $1 $2 } @@ -200,10 +200,10 @@ variableinitializer : expression { $1 } localvariabledeclarationstatement : localvariabledeclaration SEMICOLON { $1 } -statement : statementwithouttrailingsubstatement{ $1 } - -- | ifthenstatement { } - -- | ifthenelsestatement { } - -- | whilestatement { } +statement : statementwithouttrailingsubstatement{ $1 } -- statement returns a list of statements + | ifthenstatement { [$1] } + | ifthenelsestatement { [$1] } + | whilestatement { [$1] } expression : assignmentexpression { $1 } @@ -218,14 +218,14 @@ statementwithouttrailingsubstatement : block { [$1] } -- | expressionstatement { } | returnstatement { [$1] } -ifthenstatement : IF LBRACE expression RBRACE statement { } +ifthenstatement : IF LBRACE expression RBRACE statement { If $3 (Block $5) Nothing } -ifthenelsestatement : IF LBRACE expression RBRACE statementnoshortif ELSE statement { } +ifthenelsestatement : IF LBRACE expression RBRACE statementnoshortif ELSE statement { If $3 (Block $5) (Just (Block $7)) } -whilestatement : WHILE LBRACE expression RBRACE statement { } +whilestatement : WHILE LBRACE expression RBRACE statement { While $3 (Block $5) } assignmentexpression : conditionalexpression { $1 } - -- | assignment { } + | assignment { StatementExpressionExpression $1 } emptystatement : SEMICOLON { Block [] } @@ -234,14 +234,18 @@ expressionstatement : statementexpression SEMICOLON { } returnstatement : RETURN SEMICOLON { Return Nothing } | RETURN expression SEMICOLON { Return $ Just $2 } -statementnoshortif : statementwithouttrailingsubstatement { } - | ifthenelsestatementnoshortif { } - | whilestatementnoshortif { } +statementnoshortif : statementwithouttrailingsubstatement { $1 } + -- | ifthenelsestatementnoshortif { } + -- | whilestatementnoshortif { } conditionalexpression : conditionalorexpression { $1 } -- | conditionalorexpression QUESMARK expression COLON conditionalexpression { } -assignment : lefthandside assignmentoperator assignmentexpression { } +assignment : lefthandside assignmentoperator assignmentexpression { + case $2 of + Nothing -> Assignment $1 $3 + Just operator -> Assignment $1 (BinaryOperation operator $1 $3) + } statementexpression : assignment { } @@ -262,18 +266,18 @@ conditionalorexpression : conditionalandexpression { $1 } lefthandside : name { $1 } -assignmentoperator : ASSIGN{ } - -- | TIMESEQUAL { } - -- | DIVIDEEQUAL { } - -- | MODULOEQUAL { } - -- | PLUSEQUAL { } - -- | MINUSEQUAL { } +assignmentoperator : ASSIGN { Nothing } + | TIMESEQUAL { Just Multiplication } + | DIVIDEEQUAL { Just Division } + | MODULOEQUAL { Just Modulo } + | PLUSEQUAL { Just Addition } + | MINUSEQUAL { Just Subtraction } -- | SHIFTLEFTEQUAL { } -- | SIGNEDSHIFTRIGHTEQUAL { } -- | UNSIGNEDSHIFTRIGHTEQUAL { } - -- | ANDEQUAL { } - -- | XOREQUAL { } - -- | OREQUAL{ } + | ANDEQUAL { Just BitwiseAnd } + | XOREQUAL { Just BitwiseXor } + | OREQUAL{ Just BitwiseOr } preincrementexpression : INCREMENT unaryexpression { UnaryOperation PreIncrement $2 } @@ -302,7 +306,7 @@ unaryexpression : unaryexpressionnotplusminus { $1 } | preincrementexpression { $1 } postfixexpression : primary { $1 } - | name { Reference $1 } + | name { $1 } | postincrementexpression { $1 } | postdecrementexpression{ $1 } @@ -370,6 +374,9 @@ data Declarator = Declarator Identifier (Maybe Expression) convertDeclarator :: DataType -> Declarator -> VariableDeclaration convertDeclarator dataType (Declarator id assigment) = VariableDeclaration dataType id assigment +data StatementWithoutSub = Statement + + parseError :: ([Token], [String]) -> a parseError (errortoken, expected) = error ("parse error on token: " ++ show errortoken ++ "\nexpected one of: " ++ show expected)