Add initial typechecker for AST #2
@ -19,7 +19,7 @@ data Statement
|
|||||||
deriving (Show)
|
deriving (Show)
|
||||||
|
|
||||||
data StatementExpression
|
data StatementExpression
|
||||||
= Assignment Identifier Expression
|
= Assignment Expression Expression
|
||||||
| ConstructorCall DataType [Expression]
|
| ConstructorCall DataType [Expression]
|
||||||
| MethodCall Expression Identifier [Expression]
|
| MethodCall Expression Identifier [Expression]
|
||||||
| TypedStatementExpression DataType StatementExpression
|
| TypedStatementExpression DataType StatementExpression
|
||||||
|
@ -49,7 +49,7 @@ exampleExpression :: Expression
|
|||||||
exampleExpression = BinaryOperation NameResolution (Reference "bob") (Reference "age")
|
exampleExpression = BinaryOperation NameResolution (Reference "bob") (Reference "age")
|
||||||
|
|
||||||
exampleAssignment :: Expression
|
exampleAssignment :: Expression
|
||||||
exampleAssignment = StatementExpressionExpression (Assignment "a" (IntegerLiteral 30))
|
exampleAssignment = StatementExpressionExpression (Assignment (Reference "a") (IntegerLiteral 30))
|
||||||
|
|
||||||
exampleMethodCall :: Statement
|
exampleMethodCall :: Statement
|
||||||
exampleMethodCall = StatementExpressionStatement (MethodCall (Reference "this") "setAge" [IntegerLiteral 30])
|
exampleMethodCall = StatementExpressionStatement (MethodCall (Reference "this") "setAge" [IntegerLiteral 30])
|
||||||
@ -80,7 +80,7 @@ exampleMethodCallAndAssignment = Block [
|
|||||||
LocalVariableDeclaration (VariableDeclaration "int" "age" (Just (StatementExpressionExpression (MethodCall (Reference "bob") "getAge" [])))),
|
LocalVariableDeclaration (VariableDeclaration "int" "age" (Just (StatementExpressionExpression (MethodCall (Reference "bob") "getAge" [])))),
|
||||||
StatementExpressionStatement (MethodCall (Reference "bob") "setAge" [IntegerLiteral 30]),
|
StatementExpressionStatement (MethodCall (Reference "bob") "setAge" [IntegerLiteral 30]),
|
||||||
LocalVariableDeclaration (VariableDeclaration "int" "a" Nothing),
|
LocalVariableDeclaration (VariableDeclaration "int" "a" Nothing),
|
||||||
StatementExpressionStatement (Assignment "a" (Reference "age"))
|
StatementExpressionStatement (Assignment (Reference "a") (Reference "age"))
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
@ -89,7 +89,13 @@ exampleMethodCallAndAssignmentFail = Block [
|
|||||||
LocalVariableDeclaration (VariableDeclaration "Person" "bob" (Just (StatementExpressionExpression (ConstructorCall "Person" [IntegerLiteral 30])))),
|
LocalVariableDeclaration (VariableDeclaration "Person" "bob" (Just (StatementExpressionExpression (ConstructorCall "Person" [IntegerLiteral 30])))),
|
||||||
LocalVariableDeclaration (VariableDeclaration "int" "age" (Just (StatementExpressionExpression (MethodCall (Reference "bob") "getAge" [])))),
|
LocalVariableDeclaration (VariableDeclaration "int" "age" (Just (StatementExpressionExpression (MethodCall (Reference "bob") "getAge" [])))),
|
||||||
StatementExpressionStatement (MethodCall (Reference "bob") "setAge" [IntegerLiteral 30]),
|
StatementExpressionStatement (MethodCall (Reference "bob") "setAge" [IntegerLiteral 30]),
|
||||||
StatementExpressionStatement (Assignment "a" (Reference "age"))
|
StatementExpressionStatement (Assignment (Reference "age") (Reference "age"))
|
||||||
|
]
|
||||||
|
|
||||||
|
exampleNameResolutionAssignment :: Statement
|
||||||
|
exampleNameResolutionAssignment = Block [
|
||||||
|
LocalVariableDeclaration (VariableDeclaration "Person" "bob" (Just (StatementExpressionExpression (ConstructorCall "Person" [IntegerLiteral 30])))),
|
||||||
|
StatementExpressionStatement (Assignment (BinaryOperation NameResolution (Reference "bob") (Reference "age")) (IntegerLiteral 30))
|
||||||
]
|
]
|
||||||
|
|
||||||
testClasses :: [Class]
|
testClasses :: [Class]
|
||||||
@ -202,4 +208,11 @@ runTypeCheck = do
|
|||||||
printSuccess "Type checking of Program completed successfully"
|
printSuccess "Type checking of Program completed successfully"
|
||||||
printResult "Typed Program:" typedProgram
|
printResult "Typed Program:" typedProgram
|
||||||
) handleError
|
) handleError
|
||||||
|
|
||||||
|
catch (do
|
||||||
|
print "====================================================================================="
|
||||||
|
typedAssignment <- evaluate (typeCheckStatement exampleNameResolutionAssignment [] sampleClasses)
|
||||||
|
printSuccess "Type checking of name resolution assignment completed successfully"
|
||||||
|
printResult "Result Name Resolution Assignment:" typedAssignment
|
||||||
|
) handleError
|
||||||
|
|
||||||
|
@ -200,18 +200,17 @@ typeCheckExpression (StatementExpressionExpression stmtExpr) symtab classes =
|
|||||||
-- ********************************** Type Checking: StatementExpressions **********************************
|
-- ********************************** Type Checking: StatementExpressions **********************************
|
||||||
|
|
||||||
typeCheckStatementExpression :: StatementExpression -> [(Identifier, DataType)] -> [Class] -> StatementExpression
|
typeCheckStatementExpression :: StatementExpression -> [(Identifier, DataType)] -> [Class] -> StatementExpression
|
||||||
typeCheckStatementExpression (Assignment id expr) symtab classes =
|
typeCheckStatementExpression (Assignment ref expr) symtab classes =
|
||||||
let expr' = typeCheckExpression expr symtab classes
|
let expr' = typeCheckExpression expr symtab classes
|
||||||
|
ref' = typeCheckExpression ref symtab classes
|
||||||
type' = getTypeFromExpr expr'
|
type' = getTypeFromExpr expr'
|
||||||
maybeType'' = lookupType id symtab
|
type'' = getTypeFromExpr ref'
|
||||||
in case maybeType'' of
|
in
|
||||||
Just type'' ->
|
if type'' == type' then
|
||||||
if type' == type'' then
|
TypedStatementExpression type' (Assignment ref' expr')
|
||||||
TypedStatementExpression type' (Assignment id expr')
|
else
|
||||||
else
|
error $ "Type mismatch in assignment to variable: expected " ++ type'' ++ ", found " ++ type'
|
||||||
error $ "Assignment type mismatch: expected " ++ type'' ++ ", found " ++ type'
|
|
||||||
Nothing -> error $ "Identifier '" ++ id ++ "' not found in symbol table"
|
|
||||||
|
|
||||||
typeCheckStatementExpression (ConstructorCall className args) symtab classes =
|
typeCheckStatementExpression (ConstructorCall className args) symtab classes =
|
||||||
case find (\(Class name _ _) -> name == className) classes of
|
case find (\(Class name _ _) -> name == className) classes of
|
||||||
Nothing -> error $ "Class '" ++ className ++ "' not found."
|
Nothing -> error $ "Class '" ++ className ++ "' not found."
|
||||||
|
Loading…
Reference in New Issue
Block a user