diff --git a/src/Ast.hs b/src/Ast.hs index 9634ab8..a20b8e8 100644 --- a/src/Ast.hs +++ b/src/Ast.hs @@ -24,6 +24,10 @@ data StatementExpression | ConstructorCall DataType [Expression] | MethodCall Expression Identifier [Expression] | TypedStatementExpression DataType StatementExpression + | PostIncrement Expression + | PostDecrement Expression + | PreIncrement Expression + | PreDecrement Expression deriving (Show, Eq) data BinaryOperator @@ -49,10 +53,6 @@ data BinaryOperator data UnaryOperator = Not | Minus - | PostIncrement - | PostDecrement - | PreIncrement - | PreDecrement deriving (Show, Eq) data Expression diff --git a/src/Example.hs b/src/Example.hs index 080b738..03ff209 100644 --- a/src/Example.hs +++ b/src/Example.hs @@ -110,6 +110,9 @@ exampleNullDeclarationFail = LocalVariableDeclaration (VariableDeclaration "int" exampleNullAssignment :: Statement exampleNullAssignment = StatementExpressionStatement (Assignment (Reference "a") NullLiteral) +exampleIncrement :: Statement +exampleIncrement = StatementExpressionStatement (PostIncrement (Reference "a")) + testClasses :: [Class] testClasses = [ Class "Person" [ @@ -255,3 +258,10 @@ runTypeCheck = do printSuccess "Type checking of null assignment completed successfully" printResult "Result Null Assignment:" evaluatedNullAssignment ) handleError + + catch (do + print "=====================================================================================" + evaluatedIncrement <- evaluate (typeCheckStatement exampleIncrement [("a", "int")] sampleClasses) + printSuccess "Type checking of increment completed successfully" + printResult "Result Increment:" evaluatedIncrement + ) handleError diff --git a/src/Typecheck.hs b/src/Typecheck.hs index 5834f57..bac30a7 100644 --- a/src/Typecheck.hs +++ b/src/Typecheck.hs @@ -89,50 +89,11 @@ typeCheckExpression (UnaryOperation op expr) symtab classes = else error "Logical NOT operation requires an operand of type boolean" Minus -> - if type' == "int" + if type' == "int" || type' == "char" then - TypedExpression "int" (UnaryOperation op expr') - else if type' == "char" - then - TypedExpression "char" (UnaryOperation op expr') + TypedExpression type' (UnaryOperation op expr') else error "Unary minus operation requires an operand of type int or char" - PostIncrement -> - if type' == "int" - then - TypedExpression "int" (UnaryOperation op expr') - else if type' == "char" - then - TypedExpression "char" (UnaryOperation op expr') - else - error "Post-increment operation requires an operand of type int or char" - PostDecrement -> - if type' == "int" - then - TypedExpression "int" (UnaryOperation op expr') - else if type' == "char" - then - TypedExpression "char" (UnaryOperation op expr') - else - error "Post-decrement operation requires an operand of type int or char" - PreIncrement -> - if type' == "int" - then - TypedExpression "int" (UnaryOperation op expr') - else if type' == "char" - then - TypedExpression "char" (UnaryOperation op expr') - else - error "Pre-increment operation requires an operand of type int or char" - PreDecrement -> - if type' == "int" - then - TypedExpression "int" (UnaryOperation op expr') - else if type' == "char" - then - TypedExpression "char" (UnaryOperation op expr') - else - error "Pre-decrement operation requires an operand of type int or char" typeCheckExpression (StatementExpressionExpression stmtExpr) symtab classes = let stmtExpr' = typeCheckStatementExpression stmtExpr symtab classes @@ -202,6 +163,42 @@ typeCheckStatementExpression (MethodCall expr methodName args) symtab classes = Nothing -> error $ "Class for object type '" ++ objType ++ "' not found." _ -> error "Invalid object type for method call. Object must have a class type." +typeCheckStatementExpression (PostIncrement expr) symtab classes = + let expr' = typeCheckExpression expr symtab classes + type' = getTypeFromExpr expr' + in if type' == "int" || type' == "char" + then + TypedStatementExpression type' (PostIncrement expr') + else + error "Post-increment operation requires an operand of type int or char" + +typeCheckStatementExpression (PostDecrement expr) symtab classes = + let expr' = typeCheckExpression expr symtab classes + type' = getTypeFromExpr expr' + in if type' == "int" || type' == "char" + then + TypedStatementExpression type' (PostDecrement expr') + else + error "Post-decrement operation requires an operand of type int or char" + +typeCheckStatementExpression (PreIncrement expr) symtab classes = + let expr' = typeCheckExpression expr symtab classes + type' = getTypeFromExpr expr' + in if type' == "int" || type' == "char" + then + TypedStatementExpression type' (PreIncrement expr') + else + error "Pre-increment operation requires an operand of type int or char" + +typeCheckStatementExpression (PreDecrement expr) symtab classes = + let expr' = typeCheckExpression expr symtab classes + type' = getTypeFromExpr expr' + in if type' == "int" || type' == "char" + then + TypedStatementExpression type' (PreDecrement expr') + else + error "Pre-decrement operation requires an operand of type int or char" + -- ********************************** Type Checking: Statements ********************************** typeCheckStatement :: Statement -> [(Identifier, DataType)] -> [Class] -> Statement