added type to expression
Some checks are pending
Gitea Actions Demo / Explore-Gitea-Actions (push) Waiting to run
Some checks are pending
Gitea Actions Demo / Explore-Gitea-Actions (push) Waiting to run
This commit is contained in:
parent
ae872ed906
commit
c0e197e2d0
@ -9,7 +9,6 @@ public class CalculationNode extends BinaryNode {
|
|||||||
public CalculationNode calculationExpression;
|
public CalculationNode calculationExpression;
|
||||||
public EnumLineOperator operator;
|
public EnumLineOperator operator;
|
||||||
public DotNode dotExpression;
|
public DotNode dotExpression;
|
||||||
private ITypeNode typeNode;
|
|
||||||
|
|
||||||
public CalculationNode(CalculationNode calculationExpression, String operator, DotNode dotExpression) {
|
public CalculationNode(CalculationNode calculationExpression, String operator, DotNode dotExpression) {
|
||||||
this.calculationExpression = calculationExpression;
|
this.calculationExpression = calculationExpression;
|
||||||
|
@ -454,6 +454,7 @@ public class SemanticAnalyzer implements SemanticVisitor {
|
|||||||
case PLUS, MINUS:
|
case PLUS, MINUS:
|
||||||
if (calcRes.getType() instanceof BaseType calcType && dotRes.getType() instanceof BaseType dotType &&
|
if (calcRes.getType() instanceof BaseType calcType && dotRes.getType() instanceof BaseType dotType &&
|
||||||
calcType.getTypeEnum().equals(TypeEnum.INT) && dotType.getTypeEnum().equals(TypeEnum.INT)) {
|
calcType.getTypeEnum().equals(TypeEnum.INT) && dotType.getTypeEnum().equals(TypeEnum.INT)) {
|
||||||
|
calcNode.setType(new BaseType(TypeEnum.INT));
|
||||||
return new TypeCheckResult(true, new BaseType(TypeEnum.INT));
|
return new TypeCheckResult(true, new BaseType(TypeEnum.INT));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -461,10 +462,12 @@ public class SemanticAnalyzer implements SemanticVisitor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
calcNode.setType(calcNode.getType());
|
||||||
return new TypeCheckResult(calcRes.isValid(), calcRes.getType());
|
return new TypeCheckResult(calcRes.isValid(), calcRes.getType());
|
||||||
}
|
}
|
||||||
} else if (calcNode.dotExpression != null) {
|
} else if (calcNode.dotExpression != null) {
|
||||||
var dotRes = calcNode.dotExpression.accept(this);
|
var dotRes = calcNode.dotExpression.accept(this);
|
||||||
|
calcNode.setType(dotRes.getType());
|
||||||
return new TypeCheckResult(dotRes.isValid(), dotRes.getType());
|
return new TypeCheckResult(dotRes.isValid(), dotRes.getType());
|
||||||
}
|
}
|
||||||
return new TypeCheckResult(false, null);
|
return new TypeCheckResult(false, null);
|
||||||
@ -473,7 +476,9 @@ public class SemanticAnalyzer implements SemanticVisitor {
|
|||||||
@Override
|
@Override
|
||||||
public TypeCheckResult analyze(DotNode toCheck) {
|
public TypeCheckResult analyze(DotNode toCheck) {
|
||||||
if (toCheck.dotSubstractionExpression != null) {
|
if (toCheck.dotSubstractionExpression != null) {
|
||||||
return toCheck.dotSubstractionExpression.accept(this);
|
var result = toCheck.dotSubstractionExpression.accept(this);
|
||||||
|
toCheck.setType(result.getType());
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
return new TypeCheckResult(false, null);
|
return new TypeCheckResult(false, null);
|
||||||
}
|
}
|
||||||
@ -481,19 +486,35 @@ public class SemanticAnalyzer implements SemanticVisitor {
|
|||||||
@Override
|
@Override
|
||||||
public TypeCheckResult analyze(DotSubstractionNode toCheck) {
|
public TypeCheckResult analyze(DotSubstractionNode toCheck) {
|
||||||
if (toCheck.value != null) {
|
if (toCheck.value != null) {
|
||||||
return toCheck.value.accept(this);
|
var result = toCheck.value.accept(this);
|
||||||
|
toCheck.setType(result.getType());
|
||||||
|
return result;
|
||||||
} else if (toCheck.memberAccess != null) {
|
} else if (toCheck.memberAccess != null) {
|
||||||
return toCheck.memberAccess.accept(this);
|
var result = toCheck.memberAccess.accept(this);
|
||||||
|
toCheck.setType(result.getType());
|
||||||
|
return result;
|
||||||
} else if (toCheck.methodCall != null) {
|
} else if (toCheck.methodCall != null) {
|
||||||
return toCheck.methodCall.accept(this);
|
var result = toCheck.methodCall.accept(this);
|
||||||
|
toCheck.setType(result.getType());
|
||||||
|
return result;
|
||||||
} else if (toCheck.identifier != null) {
|
} else if (toCheck.identifier != null) {
|
||||||
if (currentScope.contains(toCheck.identifier)) {
|
if (currentScope.contains(toCheck.identifier)) {
|
||||||
return new TypeCheckResult(true, currentScope.getLocalVar(toCheck.identifier));
|
var type = currentScope.getLocalVar(toCheck.identifier);
|
||||||
|
toCheck.setType(type);
|
||||||
|
return new TypeCheckResult(true, type);
|
||||||
} else if (currentFields.get(toCheck.identifier) != null) {
|
} else if (currentFields.get(toCheck.identifier) != null) {
|
||||||
return new TypeCheckResult(true, currentFields.get(toCheck.identifier));
|
var type = currentFields.get(toCheck.identifier);
|
||||||
|
toCheck.setType(type);
|
||||||
|
MemberAccessNode memberAccessNode = new MemberAccessNode(false);
|
||||||
|
memberAccessNode.identifiers.add(currentClass.identifier);
|
||||||
|
memberAccessNode.identifiers.add(toCheck.identifier);
|
||||||
|
toCheck.memberAccess = memberAccessNode;
|
||||||
|
return new TypeCheckResult(true, type);
|
||||||
}
|
}
|
||||||
} else if (toCheck.calculationExpression != null) {
|
} else if (toCheck.calculationExpression != null) {
|
||||||
return toCheck.calculationExpression.accept(this);
|
var result = toCheck.calculationExpression.accept(this);
|
||||||
|
toCheck.setType(result.getType());
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -513,8 +534,8 @@ public class SemanticAnalyzer implements SemanticVisitor {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case OR, AND:
|
case OR, AND:
|
||||||
if (expResult.getType() instanceof BaseType expResultType && expResultType.getTypeEnum().equals(TypeEnum.INT) &&
|
if (expResult.getType() instanceof BaseType expResultType && expResultType.getTypeEnum().equals(TypeEnum.BOOL) &&
|
||||||
unaryResult.getType() instanceof BaseType unaryResultType && unaryResultType.getTypeEnum().equals(TypeEnum.INT)) {
|
unaryResult.getType() instanceof BaseType unaryResultType && unaryResultType.getTypeEnum().equals(TypeEnum.BOOL)) {
|
||||||
return new TypeCheckResult(true, new BaseType(TypeEnum.BOOL));
|
return new TypeCheckResult(true, new BaseType(TypeEnum.BOOL));
|
||||||
} else {
|
} else {
|
||||||
errors.add(new TypeMismatchException("Both types must be Boolean"));
|
errors.add(new TypeMismatchException("Both types must be Boolean"));
|
||||||
@ -538,13 +559,17 @@ public class SemanticAnalyzer implements SemanticVisitor {
|
|||||||
|
|
||||||
if (unary.identifier != null) {
|
if (unary.identifier != null) {
|
||||||
if (currentScope.contains(unary.identifier)) {
|
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) {
|
} else if (currentFields.get(unary.identifier) != null) {
|
||||||
MemberAccessNode memberAccessNode = new MemberAccessNode(false);
|
MemberAccessNode memberAccessNode = new MemberAccessNode(false);
|
||||||
memberAccessNode.identifiers.add(currentClass.identifier);
|
memberAccessNode.identifiers.add(currentClass.identifier);
|
||||||
memberAccessNode.identifiers.add(unary.identifier);
|
memberAccessNode.identifiers.add(unary.identifier);
|
||||||
unary.memberAccess = memberAccessNode;
|
unary.memberAccess = memberAccessNode;
|
||||||
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) {
|
} else if (unary.statement != null) {
|
||||||
var result = unary.statement.accept(this);
|
var result = unary.statement.accept(this);
|
||||||
unary.setType(result.getType());
|
unary.setType(result.getType());
|
||||||
@ -554,15 +579,19 @@ public class SemanticAnalyzer implements SemanticVisitor {
|
|||||||
}
|
}
|
||||||
} else if (unary.statement != null) {
|
} else if (unary.statement != null) {
|
||||||
var result = unary.statement.accept(this);
|
var result = unary.statement.accept(this);
|
||||||
|
unary.setType(result.getType());
|
||||||
return new TypeCheckResult(result.isValid(), result.getType());
|
return new TypeCheckResult(result.isValid(), result.getType());
|
||||||
} else if (unary.value != null) {
|
} else if (unary.value != null) {
|
||||||
var result = unary.value.accept(this);
|
var result = unary.value.accept(this);
|
||||||
|
unary.setType(result.getType());
|
||||||
return new TypeCheckResult(result.isValid(), result.getType());
|
return new TypeCheckResult(result.isValid(), result.getType());
|
||||||
} else if (unary.memberAccess != null) {
|
} else if (unary.memberAccess != null) {
|
||||||
var result = unary.memberAccess.accept(this);
|
var result = unary.memberAccess.accept(this);
|
||||||
|
unary.setType(result.getType());
|
||||||
return new TypeCheckResult(result.isValid(), result.getType());
|
return new TypeCheckResult(result.isValid(), result.getType());
|
||||||
} else if (unary.expression != null) {
|
} else if (unary.expression != null) {
|
||||||
var result = unary.expression.accept(this);
|
var result = unary.expression.accept(this);
|
||||||
|
unary.setType(result.getType());
|
||||||
return new TypeCheckResult(result.isValid(), result.getType());
|
return new TypeCheckResult(result.isValid(), result.getType());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -281,6 +281,63 @@ public class EndToTypedAstTest {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void VariableCompare(){
|
||||||
|
|
||||||
|
ASTNode tast = SemanticHelper.generateTypedASTFrom("src/test/resources/input/singleFeatureSemanticTests/VariableCompare.java");
|
||||||
|
|
||||||
|
SemanticAnalyzer.generateTast(tast);
|
||||||
|
|
||||||
|
assertTrue(SemanticAnalyzer.errors.isEmpty());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void IfExpressionInt(){
|
||||||
|
|
||||||
|
ASTNode tast = SemanticHelper.generateTypedASTFrom("src/test/resources/input/singleFeatureSemanticTests/IfExpressionInt.java");
|
||||||
|
|
||||||
|
SemanticAnalyzer.generateTast(tast);
|
||||||
|
|
||||||
|
assertFalse(SemanticAnalyzer.errors.isEmpty());
|
||||||
|
assertInstanceOf(TypeMismatchException.class, SemanticAnalyzer.errors.getFirst());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void SelectWrongMethodCauseParameter(){
|
||||||
|
|
||||||
|
ASTNode tast = SemanticHelper.generateTypedASTFrom("src/test/resources/input/singleFeatureSemanticTests/SelectWrongMethodCauseParameter.java");
|
||||||
|
|
||||||
|
SemanticAnalyzer.generateTast(tast);
|
||||||
|
|
||||||
|
assertFalse(SemanticAnalyzer.errors.isEmpty());
|
||||||
|
assertInstanceOf(TypeMismatchException.class, SemanticAnalyzer.errors.getFirst());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void SelectRightMethodCauseParameter(){
|
||||||
|
|
||||||
|
ASTNode tast = SemanticHelper.generateTypedASTFrom("src/test/resources/input/singleFeatureSemanticTests/SelectRightMethodCauseParameter.java");
|
||||||
|
|
||||||
|
SemanticAnalyzer.generateTast(tast);
|
||||||
|
|
||||||
|
assertTrue(SemanticAnalyzer.errors.isEmpty());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void VariableCalculation(){
|
||||||
|
|
||||||
|
ASTNode tast = SemanticHelper.generateTypedASTFrom("src/test/resources/input/singleFeatureSemanticTests/VariableCalculation.java");
|
||||||
|
|
||||||
|
SemanticAnalyzer.generateTast(tast);
|
||||||
|
|
||||||
|
assertTrue(SemanticAnalyzer.errors.isEmpty());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
// ------------------ Helpers ------------------
|
// ------------------ Helpers ------------------
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -14,6 +14,9 @@ import java.io.IOException;
|
|||||||
|
|
||||||
public class SemanticHelper {
|
public class SemanticHelper {
|
||||||
public static ASTNode generateTypedASTFrom(String filePath) {
|
public static ASTNode generateTypedASTFrom(String filePath) {
|
||||||
|
|
||||||
|
SemanticAnalyzer.clearAnalyzer();
|
||||||
|
|
||||||
CharStream testFile = null;
|
CharStream testFile = null;
|
||||||
try {
|
try {
|
||||||
testFile = CharStreams.fromFileName(filePath);
|
testFile = CharStreams.fromFileName(filePath);
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
// @expected: TypeMismatchException
|
|
||||||
public class Test{
|
public class Test{
|
||||||
|
|
||||||
public void test(int x){
|
public void test(int x){
|
@ -0,0 +1,22 @@
|
|||||||
|
// @expected: TypeMismatchException
|
||||||
|
public class Test{
|
||||||
|
|
||||||
|
public int i;
|
||||||
|
public boolean b;
|
||||||
|
|
||||||
|
public int test(){
|
||||||
|
|
||||||
|
return test(b);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void test(int a){
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public int test(boolean bool){
|
||||||
|
int ret = 1;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,34 @@
|
|||||||
|
class VariableCalculation{
|
||||||
|
|
||||||
|
int aPlusB(int a, int b){
|
||||||
|
return a + b;
|
||||||
|
}
|
||||||
|
|
||||||
|
int aMinusB(int a, int b){
|
||||||
|
return a - b;
|
||||||
|
}
|
||||||
|
|
||||||
|
int aTimeB(int a, int b){
|
||||||
|
return a * b;
|
||||||
|
}
|
||||||
|
|
||||||
|
int aDivB(int a, int b){
|
||||||
|
return a / b;
|
||||||
|
}
|
||||||
|
|
||||||
|
int complexCalc (int a, int b){
|
||||||
|
return a * b / 1 * 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean aSmallerB (int a, int b){
|
||||||
|
return a < b;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean aGreaterB (int a, int b){
|
||||||
|
return a > b;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean aEqualsB (int a, int b){
|
||||||
|
return a == b;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,30 @@
|
|||||||
|
class VariableCompare{
|
||||||
|
|
||||||
|
boolean trueMethod() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean falseMethod(){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean trueAndTrueMethod(){
|
||||||
|
return true && true;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean trueAndFalseMethod(){
|
||||||
|
return true && false;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean falseAndFalseMethod(){
|
||||||
|
return false && false;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean trueOrTrueMethod(){
|
||||||
|
return true || true;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean falseOrFalseMethod(){
|
||||||
|
return false || false;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user