Add initial typechecker for AST #2
@ -21,7 +21,7 @@ typeCheckMethodDeclaration (MethodDeclaration retType name params body) classFie
|
|||||||
let
|
let
|
||||||
-- Combine class fields with method parameters to form the initial symbol table for the method
|
-- Combine class fields with method parameters to form the initial symbol table for the method
|
||||||
methodParams = [(identifier, dataType) | ParameterDeclaration dataType identifier <- params]
|
methodParams = [(identifier, dataType) | ParameterDeclaration dataType identifier <- params]
|
||||||
initialSymtab = classFields ++ methodParams
|
initialSymtab = ("thisMeth", retType) : classFields ++ methodParams
|
||||||
checkedBody = typeCheckStatement body initialSymtab classes
|
checkedBody = typeCheckStatement body initialSymtab classes
|
||||||
bodyType = getTypeFromStmt checkedBody
|
bodyType = getTypeFromStmt checkedBody
|
||||||
-- Check if the type of the body matches the declared return type
|
-- Check if the type of the body matches the declared return type
|
||||||
@ -37,6 +37,7 @@ typeCheckExpression (CharacterLiteral c) _ _ = TypedExpression "char" (Character
|
|||||||
typeCheckExpression (BooleanLiteral b) _ _ = TypedExpression "boolean" (BooleanLiteral b)
|
typeCheckExpression (BooleanLiteral b) _ _ = TypedExpression "boolean" (BooleanLiteral b)
|
||||||
typeCheckExpression NullLiteral _ _ = TypedExpression "null" NullLiteral
|
typeCheckExpression NullLiteral _ _ = TypedExpression "null" NullLiteral
|
||||||
typeCheckExpression (Reference id) symtab classes =
|
typeCheckExpression (Reference id) symtab classes =
|
||||||
|
-- TODO: maybe maje exception for "this" in first lookup?
|
||||||
case lookup id symtab of
|
case lookup id symtab of
|
||||||
Just t -> TypedExpression t (LocalVariable id)
|
Just t -> TypedExpression t (LocalVariable id)
|
||||||
Nothing ->
|
Nothing ->
|
||||||
@ -208,12 +209,16 @@ typeCheckStatement (If cond thenStmt elseStmt) symtab classes =
|
|||||||
elseStmt' = case elseStmt of
|
elseStmt' = case elseStmt of
|
||||||
Just stmt -> Just (typeCheckStatement stmt symtab classes)
|
Just stmt -> Just (typeCheckStatement stmt symtab classes)
|
||||||
Nothing -> Nothing
|
Nothing -> Nothing
|
||||||
|
thenType = getTypeFromStmt thenStmt'
|
||||||
|
elseType = maybe "void" getTypeFromStmt elseStmt'
|
||||||
|
ifType = if thenType /= "void" && elseType /= "void" && thenType == elseType then thenType else "void"
|
||||||
in if getTypeFromExpr cond' == "boolean"
|
in if getTypeFromExpr cond' == "boolean"
|
||||||
then
|
then
|
||||||
TypedStatement (getTypeFromStmt thenStmt') (If cond' thenStmt' elseStmt')
|
TypedStatement ifType (If cond' thenStmt' elseStmt')
|
||||||
else
|
else
|
||||||
error "If condition must be of type boolean"
|
error "If condition must be of type boolean"
|
||||||
|
|
||||||
|
|
||||||
typeCheckStatement (LocalVariableDeclaration (VariableDeclaration dataType identifier maybeExpr)) symtab classes =
|
typeCheckStatement (LocalVariableDeclaration (VariableDeclaration dataType identifier maybeExpr)) symtab classes =
|
||||||
-- Check for redefinition in the current scope
|
-- Check for redefinition in the current scope
|
||||||
if any ((== identifier) . snd) symtab
|
if any ((== identifier) . snd) symtab
|
||||||
|
Loading…
Reference in New Issue
Block a user