diff --git a/Test/TestParser.hs b/Test/TestParser.hs index 3d05001..2767c15 100644 --- a/Test/TestParser.hs +++ b/Test/TestParser.hs @@ -238,6 +238,40 @@ testStatementPreIncrement = TestCase $ assertEqual "expect increment" [StatementExpressionStatement $ PostIncrement $ Reference "a"] $ parseStatement [IDENTIFIER "a",INCREMENT,SEMICOLON] +testForLoop = TestCase $ + assertEqual "expect for loop" [Block [ + LocalVariableDeclaration (VariableDeclaration "int" "i" (Just (IntegerLiteral 0))), + While (BinaryOperation CompareLessThan (Reference "i") (IntegerLiteral 3)) (Block [Block [], StatementExpressionStatement (PostIncrement (Reference "i"))]) + ]] $ + parseStatement [FOR,LBRACE,INT,IDENTIFIER "i",ASSIGN,INTEGERLITERAL 0,SEMICOLON,IDENTIFIER "i",LESS,INTEGERLITERAL 3,SEMICOLON,IDENTIFIER "i",INCREMENT,RBRACE,LBRACKET,RBRACKET] +testForLoopExpressionlistInInit = TestCase $ + assertEqual "expect expressionlist in init part of for loop" [Block [ + StatementExpressionStatement (PostIncrement (Reference "i")), + While (BinaryOperation CompareLessThan (Reference "i") (IntegerLiteral 3)) (Block [Block [], StatementExpressionStatement (PostIncrement (Reference "i"))]) + ]] $ + parseStatement [FOR,LBRACE,IDENTIFIER "i",INCREMENT,SEMICOLON,IDENTIFIER "i",LESS,INTEGERLITERAL 3,SEMICOLON,IDENTIFIER "i",INCREMENT,RBRACE,LBRACKET,RBRACKET] +testForLoopMultipleUpdateExpressions = TestCase $ + assertEqual "expect for loop with multiple update statements" [Block [ + LocalVariableDeclaration (VariableDeclaration "int" "i" (Just (IntegerLiteral 0))), + While (BinaryOperation CompareLessThan (Reference "i") (IntegerLiteral 3)) (Block [Block [], StatementExpressionStatement (PostIncrement (Reference "i")), StatementExpressionStatement (PostIncrement (Reference "k"))]) + ]] $ + parseStatement [FOR,LBRACE,INT,IDENTIFIER "i",ASSIGN,INTEGERLITERAL 0,SEMICOLON,IDENTIFIER "i",LESS,INTEGERLITERAL 3,SEMICOLON,IDENTIFIER "i",INCREMENT,COMMA,IDENTIFIER "k",INCREMENT,RBRACE,LBRACKET,RBRACKET] +testForLoopEmptyFirstPart = TestCase $ + assertEqual "expect for loop with empty init part" [Block [ + While (BinaryOperation CompareLessThan (Reference "i") (IntegerLiteral 3)) (Block [Block [], StatementExpressionStatement (PostIncrement (Reference "i"))]) + ]] $ + parseStatement [FOR,LBRACE,SEMICOLON,IDENTIFIER "i",LESS,INTEGERLITERAL 3,SEMICOLON,IDENTIFIER "i",INCREMENT,RBRACE,LBRACKET,RBRACKET] +testForLoopEmtpySecondPart = TestCase $ + assertEqual "expect for loop with empty expresion part" [Block [ + While (BooleanLiteral True) (Block [Block [], StatementExpressionStatement (PostIncrement (Reference "i"))]) + ]] $ + parseStatement [FOR,LBRACE,SEMICOLON,SEMICOLON,IDENTIFIER "i",INCREMENT,RBRACE,LBRACKET,RBRACKET] +testForLoopEmtpy = TestCase $ + assertEqual "expect empty for loop" [Block [While (BooleanLiteral True) (Block [Block []])]] $ + parseStatement [FOR,LBRACE,SEMICOLON,SEMICOLON,RBRACE,LBRACKET,RBRACKET] + + + tests = TestList [ testSingleEmptyClass, @@ -308,5 +342,11 @@ tests = TestList [ testStatementMethodCallNoParams, testStatementConstructorCall, testStatementConstructorCallWithArgs, - testStatementPreIncrement + testStatementPreIncrement, + testForLoop, + testForLoopExpressionlistInInit, + testForLoopMultipleUpdateExpressions, + testForLoopEmptyFirstPart, + testForLoopEmtpySecondPart, + testForLoopEmtpy ] \ No newline at end of file diff --git a/src/Parser/JavaParser.y b/src/Parser/JavaParser.y index d7dc862..3e011d1 100644 --- a/src/Parser/JavaParser.y +++ b/src/Parser/JavaParser.y @@ -75,6 +75,7 @@ import Parser.Lexer OREQUAL { OREQUAL } COLON { COLON } LESS { LESS } + FOR { FOR } %% compilationunit : typedeclarations { $1 } @@ -204,6 +205,7 @@ statement : statementwithouttrailingsubstatement{ $1 } -- statement retu | ifthenstatement { [$1] } | ifthenelsestatement { [$1] } | whilestatement { [$1] } + | forstatement { [$1] } expression : assignmentexpression { $1 } @@ -224,6 +226,21 @@ ifthenelsestatement : IF LBRACE expression RBRACE statementnoshortif ELSE state whilestatement : WHILE LBRACE expression RBRACE statement { While $3 (Block $5) } +forstatement : FOR LBRACE forinit optionalexpression forupdate statement { Block ($3 ++ [While ($4) (Block ($6 ++ $5))]) } + +forinit : statementexpressionlist SEMICOLON { $1 } + | localvariabledeclaration SEMICOLON { $1 } + | SEMICOLON { [] } + +optionalexpression : expression SEMICOLON { $1 } + | SEMICOLON { BooleanLiteral True } + +forupdate : statementexpressionlist RBRACE { $1 } + | RBRACE { [] } + +statementexpressionlist : statementexpression { [StatementExpressionStatement $1] } + | statementexpressionlist COMMA statementexpression { $1 ++ [StatementExpressionStatement $3] } + assignmentexpression : conditionalexpression { $1 } | assignment { StatementExpressionExpression $1 }