From 82356ec189ee94936c41b2442bfa9ef6d5d8664e Mon Sep 17 00:00:00 2001 From: Bruder John Date: Tue, 2 Jul 2024 10:36:22 +0200 Subject: [PATCH] set types of expressions --- .../java/ast/members/ConstructorNode.java | 1 - src/main/java/ast/members/MethodNode.java | 2 +- src/main/java/semantic/SemanticAnalyzer.java | 18 +++++- .../DuplicatedConstructor.java | 12 ++++ .../ConstructorOverloading.java | 11 ++++ .../typedAstFeaturesTests/CorrectTest.java | 61 +++++++++++++++++-- 6 files changed, 97 insertions(+), 8 deletions(-) create mode 100644 src/test/resources/input/typedAstExceptionsTests/DuplicatedConstructor.java create mode 100644 src/test/resources/input/typedAstFeaturesTests/ConstructorOverloading.java diff --git a/src/main/java/ast/members/ConstructorNode.java b/src/main/java/ast/members/ConstructorNode.java index b3fda52..71e6d89 100644 --- a/src/main/java/ast/members/ConstructorNode.java +++ b/src/main/java/ast/members/ConstructorNode.java @@ -9,7 +9,6 @@ import java.util.List; import java.util.Objects; public class ConstructorNode extends MethodNode { - public String identifier; public ConstructorNode(String accessType, String identifier, BlockNode block) { this.accesModifier = new AccessModifierNode(accessType); diff --git a/src/main/java/ast/members/MethodNode.java b/src/main/java/ast/members/MethodNode.java index 1345508..a083ca4 100644 --- a/src/main/java/ast/members/MethodNode.java +++ b/src/main/java/ast/members/MethodNode.java @@ -17,7 +17,7 @@ public class MethodNode implements MemberNode, Visitable { public AccessModifierNode accesModifier; private ITypeNode type; public Boolean voidType; - private String identifier; + protected String identifier; public List parameters = new ArrayList<>(); public BlockNode block; diff --git a/src/main/java/semantic/SemanticAnalyzer.java b/src/main/java/semantic/SemanticAnalyzer.java index 06fe7e4..5906d16 100644 --- a/src/main/java/semantic/SemanticAnalyzer.java +++ b/src/main/java/semantic/SemanticAnalyzer.java @@ -405,6 +405,7 @@ public class SemanticAnalyzer implements SemanticVisitor { case PLUS, MINUS: if (calcRes.getType() instanceof BaseType calcType && dotRes.getType() instanceof BaseType dotType && calcType.getTypeEnum().equals(TypeEnum.INT) && dotType.getTypeEnum().equals(TypeEnum.INT)) { + calcNode.setType(new BaseType(TypeEnum.INT)); return new TypeCheckResult(true, new BaseType(TypeEnum.INT)); } break; @@ -412,10 +413,12 @@ public class SemanticAnalyzer implements SemanticVisitor { } } else { + calcNode.setType(calcRes.getType()); return new TypeCheckResult(calcRes.isValid(), calcRes.getType()); } } else if (calcNode.dotExpression != null) { var dotRes = calcNode.dotExpression.accept(this); + calcNode.setType(dotRes.getType()); return new TypeCheckResult(dotRes.isValid(), dotRes.getType()); } return new TypeCheckResult(false, null); @@ -458,6 +461,7 @@ public class SemanticAnalyzer implements SemanticVisitor { case LESS, LESS_EQUAL, GREATER, GREATER_EQUAL: if (expResult.getType() instanceof BaseType expResultType && expResultType.getTypeEnum().equals(TypeEnum.INT) && unaryResult.getType() instanceof BaseType unaryResultType && unaryResultType.getTypeEnum().equals(TypeEnum.INT)) { + nonCalculationNode.setType(new BaseType(TypeEnum.BOOL)); return new TypeCheckResult(true, new BaseType(TypeEnum.BOOL)); } else { errors.add(new TypeMismatchException("Both types must be Integer")); @@ -466,6 +470,7 @@ public class SemanticAnalyzer implements SemanticVisitor { case OR, AND: if (expResult.getType() instanceof BaseType expResultType && expResultType.getTypeEnum().equals(TypeEnum.INT) && unaryResult.getType() instanceof BaseType unaryResultType && unaryResultType.getTypeEnum().equals(TypeEnum.INT)) { + nonCalculationNode.setType(new BaseType(TypeEnum.BOOL)); return new TypeCheckResult(true, new BaseType(TypeEnum.BOOL)); } else { errors.add(new TypeMismatchException("Both types must be Boolean")); @@ -474,6 +479,7 @@ public class SemanticAnalyzer implements SemanticVisitor { case EQUAL, NOT_EQUAL: if (expResult.getType() instanceof BaseType expResultType && unaryResult.getType() instanceof BaseType unaryResultType && Objects.equals(expResultType, unaryResultType)) { + nonCalculationNode.setType(new BaseType(TypeEnum.BOOL)); return new TypeCheckResult(true, new BaseType(TypeEnum.BOOL)); } else { errors.add(new TypeMismatchException("Both types must be the same")); @@ -489,9 +495,13 @@ public class SemanticAnalyzer implements SemanticVisitor { if (unary.identifier != null) { if (currentScope.contains(unary.identifier)) { - return new TypeCheckResult(valid, currentScope.getLocalVar(unary.identifier)); + var type = currentScope.getLocalVar(unary.identifier); + unary.setType(type); + return new TypeCheckResult(valid, type); } else if (currentFields.get(unary.identifier) != null) { - return new TypeCheckResult(valid, currentFields.get(unary.identifier)); + var type = currentFields.get(unary.identifier); + unary.setType(type); + return new TypeCheckResult(valid, type); } else if (unary.statement != null) { var result = unary.statement.accept(this); unary.setType(result.getType()); @@ -501,15 +511,19 @@ public class SemanticAnalyzer implements SemanticVisitor { } } else if (unary.statement != null) { var result = unary.statement.accept(this); + unary.setType(result.getType()); return new TypeCheckResult(result.isValid(), result.getType()); } else if (unary.value != null) { var result = unary.value.accept(this); + unary.setType(result.getType()); return new TypeCheckResult(result.isValid(), result.getType()); } else if (unary.memberAccess != null) { var result = unary.memberAccess.accept(this); + unary.setType(result.getType()); return new TypeCheckResult(result.isValid(), result.getType()); } else if (unary.expression != null) { var result = unary.expression.accept(this); + unary.setType(result.getType()); return new TypeCheckResult(result.isValid(), result.getType()); } diff --git a/src/test/resources/input/typedAstExceptionsTests/DuplicatedConstructor.java b/src/test/resources/input/typedAstExceptionsTests/DuplicatedConstructor.java new file mode 100644 index 0000000..3d877a3 --- /dev/null +++ b/src/test/resources/input/typedAstExceptionsTests/DuplicatedConstructor.java @@ -0,0 +1,12 @@ +// @expected: AlreadyDeclaredException +public class AllFeaturesClassExample { + + public AllFeaturesClassExample(boolean b){ + + } + + public AllFeaturesClassExample(boolean b){ + + } + +} diff --git a/src/test/resources/input/typedAstFeaturesTests/ConstructorOverloading.java b/src/test/resources/input/typedAstFeaturesTests/ConstructorOverloading.java new file mode 100644 index 0000000..1e0bc49 --- /dev/null +++ b/src/test/resources/input/typedAstFeaturesTests/ConstructorOverloading.java @@ -0,0 +1,11 @@ +public class AllFeaturesClassExample { + + public AllFeaturesClassExample(boolean b){ + + } + + public AllFeaturesClassExample(boolean b, int a){ + + } + +} diff --git a/src/test/resources/input/typedAstFeaturesTests/CorrectTest.java b/src/test/resources/input/typedAstFeaturesTests/CorrectTest.java index 828f6f3..5c3a97b 100644 --- a/src/test/resources/input/typedAstFeaturesTests/CorrectTest.java +++ b/src/test/resources/input/typedAstFeaturesTests/CorrectTest.java @@ -1,11 +1,64 @@ -public class AllFeaturesClassExample { - public void controlStructures(int a, boolean b) { +public class AllFeaturesClassExample { + int a; + boolean b; + char c; + + public void controlStructures(int adf, boolean bool) { + if (a > (10 + 8)) { + } else { + } + + + while (a > adf) { + a--; + } + + for (int i = 0; i < 5; i++) { + } + } - public AllFeaturesClassExample(boolean b){ - +// void logicalOperations() { +// // Logische UND-Operation +// if (b && a > 5) { +//// System.out.println("a ist größer als 5 und b ist wahr"); +// } +// +// // Logische ODER-Operation +// if (b || a < 5) { +//// System.out.println("b ist wahr oder a ist kleiner als 5"); +// } +// } + +// public static void main(String[] args) { +// AllFeaturesClassExample obj = new AllFeaturesClassExample(12, true, 'a'); +// obj.controlStructures(); +// } +} + +public class Test { + + public Car c; + + public int test(boolean b, int x) { + if (b == true) { + return c.getSpeed(); + } else { + return x; + } } } + +public class Car { + + private int speed; + + public int getSpeed() { + return speed; + } + +} +