Compare commits
No commits in common. "fb5372bc8f9b4906cd9299c0a1dccf855782a2db" and "084808c3ab2c2cc8fc155e097cd2a196463ce3ed" have entirely different histories.
fb5372bc8f
...
084808c3ab
35
pom.xml
35
pom.xml
@ -23,24 +23,6 @@
|
|||||||
<version>5.11.0-M2</version>
|
<version>5.11.0-M2</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
|
||||||
<groupId>org.junit.platform</groupId>
|
|
||||||
<artifactId>junit-platform-suite-engine</artifactId>
|
|
||||||
<version>1.11.0-M2</version>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.junit.jupiter</groupId>
|
|
||||||
<artifactId>junit-jupiter-api</artifactId>
|
|
||||||
<version>5.11.0-M2</version>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>junit</groupId>
|
|
||||||
<artifactId>junit</artifactId>
|
|
||||||
<version>4.13.1</version>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.antlr</groupId>
|
<groupId>org.antlr</groupId>
|
||||||
<artifactId>antlr4-runtime</artifactId>
|
<artifactId>antlr4-runtime</artifactId>
|
||||||
@ -62,6 +44,18 @@
|
|||||||
<version>3.26.0</version>
|
<version>3.26.0</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.junit.jupiter</groupId>
|
||||||
|
<artifactId>junit-jupiter-api</artifactId>
|
||||||
|
<version>5.11.0-M2</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.mockito</groupId>
|
||||||
|
<artifactId>mockito-core</artifactId>
|
||||||
|
<version>5.11.0</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
@ -71,11 +65,6 @@
|
|||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-surefire-plugin</artifactId>
|
<artifactId>maven-surefire-plugin</artifactId>
|
||||||
<version>3.0.0-M5</version> <!-- Change the version as needed -->
|
<version>3.0.0-M5</version> <!-- Change the version as needed -->
|
||||||
<configuration>
|
|
||||||
<includes>
|
|
||||||
<include>**/*Test.java</include>
|
|
||||||
</includes>
|
|
||||||
</configuration>
|
|
||||||
</plugin>
|
</plugin>
|
||||||
<plugin>
|
<plugin>
|
||||||
<artifactId>maven-assembly-plugin</artifactId>
|
<artifactId>maven-assembly-plugin</artifactId>
|
||||||
|
68
readme.md
68
readme.md
@ -1,68 +0,0 @@
|
|||||||
# "Nicht Haskel 2.0" Java Compiler
|
|
||||||
|
|
||||||
Realisation of a subset of the Java Standard Compiler in the course Compiler Construction of the 4th semester Computer Science at the Duale Hochschule Suttgart (Horb).
|
|
||||||
|
|
||||||
This project aims to provide a simplified version of the Java compiler, focusing on key language features and demonstrating the principles of compiler construction.
|
|
||||||
|
|
||||||
## Realised Java syntax
|
|
||||||
|
|
||||||
- **Data types**: `int`, `boolean`, `char`
|
|
||||||
- **Access modifier**: `public`, `protected`, `private`
|
|
||||||
- **Operators**: `=` `+` `-` `*` `%` `/` `>` `<` `>=` `<=` `==` `!=` `!` `&&` `||` `++` `--`
|
|
||||||
- **Keywords**: `class`, `this`, `while`, `do`, `if`, `else`, `for`, `return`, `new`, `switch`, `case`, `break`, `default`, `:`
|
|
||||||
- **Statements**:
|
|
||||||
- `if` ... `if else` ... `else`;
|
|
||||||
- `while` ... ;
|
|
||||||
- `do` ... `while`;
|
|
||||||
- `for`;
|
|
||||||
- `switch` ... `case` ... ;
|
|
||||||
- **Comments**:
|
|
||||||
- Single line: `// comment`
|
|
||||||
- Multi-line: `/* comment */`
|
|
||||||
- **Further functions**:
|
|
||||||
- All methods are overloadable
|
|
||||||
- High maintainability and expandability through implementation of the visitor pattern
|
|
||||||
- Logging Input and Outputs
|
|
||||||
- Error Handling in the Semantic Check
|
|
||||||
|
|
||||||
## Project Structure
|
|
||||||
|
|
||||||
```plain
|
|
||||||
src/
|
|
||||||
└── main/
|
|
||||||
├── java/
|
|
||||||
│ ├── ast/ -> Defining the structure of the AST
|
|
||||||
│ ├── bytecode/ -> Generate Java bytecode
|
|
||||||
│ ├── main/ -> Running the compiler
|
|
||||||
│ ├── parser/
|
|
||||||
│ │ ├── astBuilder/ -> Builder creating the AST
|
|
||||||
│ │ ├── generated/ -> Antlr generated grammar
|
|
||||||
│ │ └── grammar/ -> Antlr grammar
|
|
||||||
│ ├── semantic/ -> Running the semantic check
|
|
||||||
│ └── visitor/ -> Visitor interface
|
|
||||||
└── resources/
|
|
||||||
test/
|
|
||||||
└── java/
|
|
||||||
│ ├── main/ -> MainTest, E2ETests, UtilityTests
|
|
||||||
│ ├── parser/ -> Performs tests on the parser
|
|
||||||
│ └── semantic/ -> Performs tests on the semantic check
|
|
||||||
└── resources/ -> Ressources for running the Tests
|
|
||||||
```
|
|
||||||
|
|
||||||
## Class-Diagramm AST
|
|
||||||
|
|
||||||
![AST Diagramm](ast.png)
|
|
||||||
|
|
||||||
## Used Tools
|
|
||||||
|
|
||||||
- [Maven 4.0](https://maven.apache.org/index.html)
|
|
||||||
- Used for automating the build process and managing dependencies.
|
|
||||||
- [ANTLR4 v.13.1](https://www.antlr.org/)
|
|
||||||
- Used to parse the input Java code into the Abstract Syntax Tree.
|
|
||||||
|
|
||||||
|
|
||||||
## How to run the compiler
|
|
||||||
|
|
||||||
## Download
|
|
||||||
|
|
||||||
```bash
|
|
@ -9,6 +9,7 @@ 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;
|
||||||
|
@ -316,13 +316,9 @@ public class SemanticAnalyzer implements SemanticVisitor {
|
|||||||
@Override
|
@Override
|
||||||
public TypeCheckResult analyze(IfElseNode toCheck) {
|
public TypeCheckResult analyze(IfElseNode toCheck) {
|
||||||
var resultIf = toCheck.ifStatement.accept(this);
|
var resultIf = toCheck.ifStatement.accept(this);
|
||||||
if(toCheck.elseStatement != null){
|
var resultElse = toCheck.elseStatement.accept(this);
|
||||||
var resultElse = toCheck.elseStatement.accept(this);
|
|
||||||
return new TypeCheckResult(resultIf.isValid() && resultElse.isValid(), new BaseType(TypeEnum.VOID));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
return new TypeCheckResult(resultIf.isValid() && resultElse.isValid(), new BaseType(TypeEnum.VOID));
|
||||||
return new TypeCheckResult(resultIf.isValid(), new BaseType(TypeEnum.VOID));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -458,7 +454,6 @@ 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;
|
||||||
@ -466,12 +461,10 @@ 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);
|
||||||
@ -480,9 +473,7 @@ 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) {
|
||||||
var result = toCheck.dotSubstractionExpression.accept(this);
|
return toCheck.dotSubstractionExpression.accept(this);
|
||||||
toCheck.setType(result.getType());
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
return new TypeCheckResult(false, null);
|
return new TypeCheckResult(false, null);
|
||||||
}
|
}
|
||||||
@ -490,35 +481,19 @@ 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) {
|
||||||
var result = toCheck.value.accept(this);
|
return toCheck.value.accept(this);
|
||||||
toCheck.setType(result.getType());
|
|
||||||
return result;
|
|
||||||
} else if (toCheck.memberAccess != null) {
|
} else if (toCheck.memberAccess != null) {
|
||||||
var result = toCheck.memberAccess.accept(this);
|
return toCheck.memberAccess.accept(this);
|
||||||
toCheck.setType(result.getType());
|
|
||||||
return result;
|
|
||||||
} else if (toCheck.methodCall != null) {
|
} else if (toCheck.methodCall != null) {
|
||||||
var result = toCheck.methodCall.accept(this);
|
return 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)) {
|
||||||
var type = currentScope.getLocalVar(toCheck.identifier);
|
return new TypeCheckResult(true, 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) {
|
||||||
var type = currentFields.get(toCheck.identifier);
|
return new TypeCheckResult(true, 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) {
|
||||||
var result = toCheck.calculationExpression.accept(this);
|
return toCheck.calculationExpression.accept(this);
|
||||||
toCheck.setType(result.getType());
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -538,8 +513,8 @@ public class SemanticAnalyzer implements SemanticVisitor {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case OR, AND:
|
case OR, AND:
|
||||||
if (expResult.getType() instanceof BaseType expResultType && expResultType.getTypeEnum().equals(TypeEnum.BOOL) &&
|
if (expResult.getType() instanceof BaseType expResultType && expResultType.getTypeEnum().equals(TypeEnum.INT) &&
|
||||||
unaryResult.getType() instanceof BaseType unaryResultType && unaryResultType.getTypeEnum().equals(TypeEnum.BOOL)) {
|
unaryResult.getType() instanceof BaseType unaryResultType && unaryResultType.getTypeEnum().equals(TypeEnum.INT)) {
|
||||||
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"));
|
||||||
@ -563,17 +538,13 @@ public class SemanticAnalyzer implements SemanticVisitor {
|
|||||||
|
|
||||||
if (unary.identifier != null) {
|
if (unary.identifier != null) {
|
||||||
if (currentScope.contains(unary.identifier)) {
|
if (currentScope.contains(unary.identifier)) {
|
||||||
var type = currentScope.getLocalVar(unary.identifier);
|
return new TypeCheckResult(valid, 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;
|
||||||
var type = currentFields.get(unary.identifier);
|
return new TypeCheckResult(valid, 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());
|
||||||
@ -583,19 +554,15 @@ 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());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,6 +8,7 @@ public class Node {
|
|||||||
public void main() {
|
public void main() {
|
||||||
Compiler compiler = new Compiler();
|
Compiler compiler = new Compiler();
|
||||||
int i = compiler.add(5, 8);
|
int i = compiler.add(5, 8);
|
||||||
|
return i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10,7 +10,13 @@ compile-javac:
|
|||||||
compile-raupenpiler:
|
compile-raupenpiler:
|
||||||
cd ../.. ; mvn -DskipTests install
|
cd ../.. ; mvn -DskipTests install
|
||||||
cd ../.. ; mvn exec:java -DgenJar=true -DgenClass=true -Dexec.mainClass="main.Main" -Dexec.args="'src/main/resources/input/CompilerInput.java' 'src/main/resources/output'"
|
cd ../.. ; mvn exec:java -DgenJar=true -DgenClass=true -Dexec.mainClass="main.Main" -Dexec.args="'src/main/resources/input/CompilerInput.java' 'src/main/resources/output'"
|
||||||
# cp ../main/resources/output/CompilerInput.class .java/resources/output/raupenpiler
|
cp ../main/resources/output/CompilerInput.class .java/resources/output/raupenpiler
|
||||||
|
|
||||||
|
test: compile-javac compile-raupenpiler test-javac test-raupenpiler
|
||||||
|
|
||||||
|
test-javac:
|
||||||
|
# gleich wie bei raupenpiler, kann ich ohne funktionierenden Compiler nicht testen
|
||||||
|
|
||||||
|
|
||||||
test-raupenpiler:
|
test-raupenpiler:
|
||||||
# move the compiled class to the test/main folder
|
# move the compiled class to the test/main folder
|
||||||
@ -23,19 +29,17 @@ test-raupenpiler:
|
|||||||
|
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
# clean main output folders
|
# clean output folders
|
||||||
rm -f ../main/resources/output/*.class
|
rm -f ../main/resources/output/*.class
|
||||||
rm -f ../main/resources/output/*.jar
|
rm -f ../main/resources/output/*.jar
|
||||||
# clean resources output folders
|
|
||||||
rm -f ./resources/output/javac/*.class
|
rm -f ./resources/output/javac/*.class
|
||||||
rm -f ./resources/output/raupenpiler/*.class
|
rm -f ./resources/output/raupenpiler/*.class
|
||||||
rm -f ./resources/output/raupenpiler/*.jar
|
|
||||||
# clean logs
|
# clean logs
|
||||||
rm -f ../main/resources/logs/*
|
rm -f ../main/resources/logs/*.log
|
||||||
# clean test/java/main folders from .class files for End-to-End tests
|
# clean test/java/main folders from .class files for End-to-End tests
|
||||||
rm -f ./java/main/*.class
|
rm -f ./java/main/*.class
|
||||||
# clean javac output from every folder
|
# clean javac output from combinedFeatureTests
|
||||||
rm -f ./resources/input/*/*.class
|
rm -f ./resources/input/combinedFeatureTests/*.class
|
||||||
# clean test results from maven surefire plugin
|
rm -f ./resources/input/singleFeatureTests/*.class
|
||||||
rm -f ../../target/surefire-reports/*.txt
|
rm -f ./resources/input/typedAstFeatureTests/*.class
|
||||||
|
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -1,6 +1,5 @@
|
|||||||
package main;
|
package main;
|
||||||
|
|
||||||
import org.junit.jupiter.api.Disabled;
|
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
import javax.tools.JavaCompiler;
|
import javax.tools.JavaCompiler;
|
||||||
@ -27,17 +26,13 @@ public class InputFilesTest {
|
|||||||
// Assert that the compiler is available
|
// Assert that the compiler is available
|
||||||
assertNotNull(javac, "Java Compiler is not available");
|
assertNotNull(javac, "Java Compiler is not available");
|
||||||
|
|
||||||
File combinedFeatureTests = new File("src/test/resources/input/combinedFeatureTests");
|
File folder1 = new File("src/test/resources/input/combinedFeatureTests");
|
||||||
File endabgabeTests = new File("src/test/resources/input/endabgabeTests");
|
File folder2 = new File("src/test/resources/input/singleFeatureTests");
|
||||||
File singleFeatureSemanticTests = new File("src/test/resources/input/singleFeatureSemanticTests");
|
File folder3 = new File("src/test/resources/input/typedAstFeatureTests");
|
||||||
File singleFeatureTests = new File("src/test/resources/input/singleFeatureTests");
|
|
||||||
File typedAstFeatureTests = new File("src/test/resources/input/typedAstFeatureTests");
|
|
||||||
|
|
||||||
List<File> files = getJavaFilesFromDirectory(combinedFeatureTests);
|
List<File> files = getJavaFilesFromDirectory(folder1);
|
||||||
// files.addAll(getJavaFilesFromDirectory(endabgabeTests));
|
files.addAll(getJavaFilesFromDirectory(folder2));
|
||||||
// files.addAll(getJavaFilesFromDirectory(singleFeatureSemanticTests));
|
files.addAll(getJavaFilesFromDirectory(folder3));
|
||||||
files.addAll(getJavaFilesFromDirectory(singleFeatureTests));
|
|
||||||
// files.addAll(getJavaFilesFromDirectory(typedAstFeatureTests));
|
|
||||||
|
|
||||||
if (!files.isEmpty()) {
|
if (!files.isEmpty()) {
|
||||||
for (File file : files) {
|
for (File file : files) {
|
||||||
@ -52,133 +47,6 @@ public class InputFilesTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
public void areCombinedFeatureTestsValid() throws IOException {
|
|
||||||
// Get the system Java compiler
|
|
||||||
JavaCompiler javac = ToolProvider.getSystemJavaCompiler();
|
|
||||||
// Assert that the compiler is available
|
|
||||||
assertNotNull(javac, "Java Compiler is not available");
|
|
||||||
|
|
||||||
File combinedFeatureTests = new File("src/test/resources/input/combinedFeatureTests");
|
|
||||||
|
|
||||||
List<File> files = getJavaFilesFromDirectory(combinedFeatureTests);
|
|
||||||
|
|
||||||
if (!files.isEmpty()) {
|
|
||||||
for (File file : files) {
|
|
||||||
// Try to compile the file and get the result
|
|
||||||
int result = javac.run(null, null, null, file.getPath());
|
|
||||||
|
|
||||||
// Assert that the compilation succeeded (i.e., the result is zero)
|
|
||||||
assertEquals(0, result, "Expected compilation success for " + file.getName());
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
System.out.println("No files found in the directories.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
@Disabled
|
|
||||||
public void areEndabgabeTestsActuallyValid() throws IOException {
|
|
||||||
// Get the system Java compiler
|
|
||||||
JavaCompiler javac = ToolProvider.getSystemJavaCompiler();
|
|
||||||
// Assert that the compiler is available
|
|
||||||
assertNotNull(javac, "Java Compiler is not available");
|
|
||||||
|
|
||||||
File endabgabeTests = new File("src/test/resources/input/endabgabeTests");
|
|
||||||
|
|
||||||
List<File> files = getJavaFilesFromDirectory(endabgabeTests);
|
|
||||||
|
|
||||||
if (!files.isEmpty()) {
|
|
||||||
for (File file : files) {
|
|
||||||
// Try to compile the file and get the result
|
|
||||||
int result = javac.run(null, null, null, file.getPath());
|
|
||||||
|
|
||||||
// Assert that the compilation succeeded (i.e., the result is zero)
|
|
||||||
assertEquals(0, result, "Expected compilation success for " + file.getName());
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
System.out.println("No files found in the directories.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
@Disabled
|
|
||||||
public void areSingleFeatureSemanticTestsActuallyValid() throws IOException {
|
|
||||||
// Get the system Java compiler
|
|
||||||
JavaCompiler javac = ToolProvider.getSystemJavaCompiler();
|
|
||||||
// Assert that the compiler is available
|
|
||||||
assertNotNull(javac, "Java Compiler is not available");
|
|
||||||
|
|
||||||
File singleFeatureSemanticTests = new File("src/test/resources/input/singleFeatureSemanticTests");
|
|
||||||
|
|
||||||
List<File> files = getJavaFilesFromDirectory(singleFeatureSemanticTests);
|
|
||||||
|
|
||||||
if (!files.isEmpty()) {
|
|
||||||
for (File file : files) {
|
|
||||||
// Try to compile the file and get the result
|
|
||||||
int result = javac.run(null, null, null, file.getPath());
|
|
||||||
|
|
||||||
// Assert that the compilation succeeded (i.e., the result is zero)
|
|
||||||
assertEquals(0, result, "Expected compilation success for " + file.getName());
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
System.out.println("No files found in the directories.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void areSingleFeatureTestsActuallyValid() throws IOException {
|
|
||||||
// Get the system Java compiler
|
|
||||||
JavaCompiler javac = ToolProvider.getSystemJavaCompiler();
|
|
||||||
// Assert that the compiler is available
|
|
||||||
assertNotNull(javac, "Java Compiler is not available");
|
|
||||||
|
|
||||||
File singleFeatureTests = new File("src/test/resources/input/singleFeatureTests");
|
|
||||||
|
|
||||||
List<File> files = getJavaFilesFromDirectory(singleFeatureTests);
|
|
||||||
|
|
||||||
if (!files.isEmpty()) {
|
|
||||||
for (File file : files) {
|
|
||||||
// Try to compile the file and get the result
|
|
||||||
int result = javac.run(null, null, null, file.getPath());
|
|
||||||
|
|
||||||
// Assert that the compilation succeeded (i.e., the result is zero)
|
|
||||||
assertEquals(0, result, "Expected compilation success for " + file.getName());
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
System.out.println("No files found in the directories.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Test
|
|
||||||
@Disabled
|
|
||||||
public void areTypedAstFeatureTestsActuallyValid() throws IOException {
|
|
||||||
// Get the system Java compiler
|
|
||||||
JavaCompiler javac = ToolProvider.getSystemJavaCompiler();
|
|
||||||
// Assert that the compiler is available
|
|
||||||
assertNotNull(javac, "Java Compiler is not available");
|
|
||||||
|
|
||||||
File typedAstFeatureTests = new File("src/test/resources/input/typedAstFeatureTests");
|
|
||||||
|
|
||||||
List<File> files = getJavaFilesFromDirectory(typedAstFeatureTests);
|
|
||||||
|
|
||||||
if (!files.isEmpty()) {
|
|
||||||
for (File file : files) {
|
|
||||||
// Try to compile the file and get the result
|
|
||||||
int result = javac.run(null, null, null, file.getPath());
|
|
||||||
|
|
||||||
// Assert that the compilation succeeded (i.e., the result is zero)
|
|
||||||
assertEquals(0, result, "Expected compilation success for " + file.getName());
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
System.out.println("No files found in the directories.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This test method checks if invalid Java files fail to compile as expected.
|
* This test method checks if invalid Java files fail to compile as expected.
|
||||||
|
@ -1,25 +1,28 @@
|
|||||||
package main;
|
package main;
|
||||||
|
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.junit.runners.Suite;
|
import org.antlr.v4.runtime.CharStream;
|
||||||
import parser.ParserTest;
|
import org.antlr.v4.runtime.CharStreams;
|
||||||
import parser.ScannerTest;
|
|
||||||
import semantic.EndToTypedAstTest;
|
import java.io.IOException;
|
||||||
import semantic.SemanticTest;
|
import java.nio.file.Paths;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class is a test suite that runs all the test classes in the project.
|
* run every test: mvn test
|
||||||
* <p> run: <code> mvn test </code>
|
* Nutzen dieser Klasse: Eigentlich nicht vorhanden, in der Main gibts nichts zu testen
|
||||||
* <p> check results in console or <code> target/surefire-reports </code>
|
|
||||||
*/
|
*/
|
||||||
@RunWith(Suite.class)
|
|
||||||
@Suite.SuiteClasses({
|
|
||||||
InputFilesTest.class,
|
|
||||||
ScannerTest.class,
|
|
||||||
ParserTest.class,
|
|
||||||
SemanticTest.class,
|
|
||||||
EndToTypedAstTest.class
|
|
||||||
})
|
|
||||||
public class MainTest {
|
public class MainTest {
|
||||||
// This class remains empty, it is used only as a holder for the above annotations
|
@Test
|
||||||
|
void test() {
|
||||||
|
CharStream codeCharStream = null;
|
||||||
|
try {
|
||||||
|
codeCharStream = CharStreams.fromPath(Paths.get("src/main/test/resources/CompilerInput.java"));
|
||||||
|
Main.compileFile(codeCharStream, "src/main/test/resources/output");
|
||||||
|
} catch (IOException e) {
|
||||||
|
System.err.println("Error reading the file: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
145
src/test/java/main/ReflectionsTest.java
Normal file
145
src/test/java/main/ReflectionsTest.java
Normal file
@ -0,0 +1,145 @@
|
|||||||
|
package main;
|
||||||
|
|
||||||
|
import java.lang.reflect.Constructor;
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.antlr.v4.runtime.CharStream;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
|
|
||||||
|
|
||||||
|
public class ReflectionsTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSimpleJavaLexerClass() throws ClassNotFoundException, NoSuchMethodException {
|
||||||
|
Class<?> clazz = Class.forName("parser.generated.SimpleJavaLexer");
|
||||||
|
|
||||||
|
// Class Name
|
||||||
|
assertEquals("parser.generated.SimpleJavaLexer", clazz.getName());
|
||||||
|
|
||||||
|
// Constructors
|
||||||
|
Constructor<?>[] actualConstructors = clazz.getDeclaredConstructors();
|
||||||
|
assertTrue(actualConstructors.length > 0, "No constructors found");
|
||||||
|
|
||||||
|
Constructor<?> expectedConstructor = clazz.getConstructor(CharStream.class);
|
||||||
|
|
||||||
|
boolean constructorFound = false;
|
||||||
|
for (Constructor<?> constructor : actualConstructors) {
|
||||||
|
if (constructor.equals(expectedConstructor)) {
|
||||||
|
constructorFound = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assertTrue(constructorFound, "Expected constructor not found in actual constructors");
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Methods
|
||||||
|
Method[] actualMethodNames = clazz.getDeclaredMethods();
|
||||||
|
assertTrue(actualMethodNames.length > 0);
|
||||||
|
Arrays.stream(actualMethodNames).forEach(method -> System.out.println("Method: " + method.getName()));
|
||||||
|
|
||||||
|
List<String> expectedMethodNames = Arrays.asList(
|
||||||
|
"getTokenNames",
|
||||||
|
"getVocabulary",
|
||||||
|
"getGrammarFileName",
|
||||||
|
"getRuleNames",
|
||||||
|
"getSerializedATN",
|
||||||
|
"getChannelNames",
|
||||||
|
"getModeNames",
|
||||||
|
"getATN",
|
||||||
|
"makeRuleNames",
|
||||||
|
"makeLiteralNames",
|
||||||
|
"makeSymbolicNames"
|
||||||
|
);
|
||||||
|
|
||||||
|
for (Method method : actualMethodNames) {
|
||||||
|
assertTrue(expectedMethodNames.contains(method.getName()));
|
||||||
|
}
|
||||||
|
|
||||||
|
for (String expectedMethodName : expectedMethodNames) {
|
||||||
|
boolean methodFound = false;
|
||||||
|
for (Method method : actualMethodNames) {
|
||||||
|
if (method.getName().equals(expectedMethodName)) {
|
||||||
|
methodFound = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assertTrue(methodFound, "Expected method " + expectedMethodName + " not found in actual methods");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Fields
|
||||||
|
Field[] actualFieldNames = clazz.getDeclaredFields();
|
||||||
|
assertTrue(actualFieldNames.length > 0);
|
||||||
|
Arrays.stream(actualFieldNames).forEach(field -> System.out.println("Field: " + field.getName()));
|
||||||
|
|
||||||
|
List<String> expectedFieldNames = Arrays.asList(
|
||||||
|
"_decisionToDFA",
|
||||||
|
"_sharedContextCache",
|
||||||
|
"channelNames",
|
||||||
|
"modeNames",
|
||||||
|
"ruleNames",
|
||||||
|
"_LITERAL_NAMES",
|
||||||
|
"_SYMBOLIC_NAMES",
|
||||||
|
"VOCABULARY",
|
||||||
|
"tokenNames",
|
||||||
|
"_serializedATN",
|
||||||
|
"_ATN"
|
||||||
|
);
|
||||||
|
|
||||||
|
for (Field field : actualFieldNames) {
|
||||||
|
assertTrue(expectedFieldNames.contains(field.getName()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSimpleJavaParserClass() throws ClassNotFoundException {
|
||||||
|
Class<?> clazz = Class.forName("parser.generated.SimpleJavaParser");
|
||||||
|
|
||||||
|
// Class Name
|
||||||
|
assertEquals("parser.generated.SimpleJavaParser", clazz.getName());
|
||||||
|
|
||||||
|
// Constructors
|
||||||
|
Constructor<?>[] constructors = clazz.getDeclaredConstructors();
|
||||||
|
assertTrue(constructors.length > 0);
|
||||||
|
|
||||||
|
// Methods
|
||||||
|
Method[] methods = clazz.getDeclaredMethods();
|
||||||
|
assertTrue(methods.length > 0);
|
||||||
|
Arrays.stream(methods).forEach(method -> System.out.println("Method: " + method.getName()));
|
||||||
|
|
||||||
|
// Fields
|
||||||
|
Field[] fields = clazz.getDeclaredFields();
|
||||||
|
assertTrue(fields.length > 0);
|
||||||
|
Arrays.stream(fields).forEach(field -> System.out.println("Field: " + field.getName()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testASTBuilderClass() throws ClassNotFoundException {
|
||||||
|
Class<?> clazz = Class.forName("parser.astBuilder.ASTBuilder");
|
||||||
|
|
||||||
|
// Class Name
|
||||||
|
assertEquals("parser.astBuilder.ASTBuilder", clazz.getName());
|
||||||
|
|
||||||
|
// Constructors
|
||||||
|
Constructor<?>[] constructors = clazz.getDeclaredConstructors();
|
||||||
|
assertTrue(constructors.length > 0);
|
||||||
|
|
||||||
|
// Methods
|
||||||
|
Method[] methods = clazz.getDeclaredMethods();
|
||||||
|
assertTrue(methods.length > 0);
|
||||||
|
Arrays.stream(methods).forEach(method -> System.out.println("Method: " + method.getName()));
|
||||||
|
|
||||||
|
// Fields
|
||||||
|
Field[] fields = clazz.getDeclaredFields();
|
||||||
|
assertTrue(fields.length > 0);
|
||||||
|
Arrays.stream(fields).forEach(field -> System.out.println("Field: " + field.getName()));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Similarly, you can add tests for SemanticAnalyzer and ByteCodeGenerator
|
||||||
|
}
|
45
src/test/java/semantic/BeginnToTAST.java
Normal file
45
src/test/java/semantic/BeginnToTAST.java
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
package semantic;
|
||||||
|
|
||||||
|
import ast.ProgramNode;
|
||||||
|
import org.antlr.v4.runtime.CharStream;
|
||||||
|
import org.antlr.v4.runtime.CharStreams;
|
||||||
|
import org.antlr.v4.runtime.CommonTokenStream;
|
||||||
|
import org.antlr.v4.runtime.tree.ParseTree;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import parser.astBuilder.ASTBuilder;
|
||||||
|
import parser.generated.SimpleJavaLexer;
|
||||||
|
import parser.generated.SimpleJavaParser;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.file.Paths;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
|
|
||||||
|
public class BeginnToTAST {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void FieldTests() {
|
||||||
|
SemanticAnalyzer.clearAnalyzer();
|
||||||
|
|
||||||
|
CharStream codeCharStream = null;
|
||||||
|
try {
|
||||||
|
codeCharStream = CharStreams.fromPath(Paths.get("src/test/resources/input/johnsTests/FieldTests.java"));
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
SimpleJavaLexer lexer = new SimpleJavaLexer(codeCharStream);
|
||||||
|
CommonTokenStream tokenStream = new CommonTokenStream(lexer);
|
||||||
|
|
||||||
|
SimpleJavaParser parser = new SimpleJavaParser(tokenStream);
|
||||||
|
ParseTree parseTree = parser.program(); // parse the input
|
||||||
|
|
||||||
|
/* ------------------------- AST builder -> AST ------------------------- */
|
||||||
|
ASTBuilder astBuilder = new ASTBuilder();
|
||||||
|
ProgramNode abstractSyntaxTree = (ProgramNode) astBuilder.visit(parseTree);
|
||||||
|
|
||||||
|
var result = SemanticAnalyzer.generateTast(abstractSyntaxTree);
|
||||||
|
|
||||||
|
assertTrue(SemanticAnalyzer.errors.isEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -281,74 +281,6 @@ 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());
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void Expression(){
|
|
||||||
|
|
||||||
ASTNode tast = SemanticHelper.generateTypedASTFrom("src/test/resources/input/singleFeatureSemanticTests/Expression.java");
|
|
||||||
|
|
||||||
SemanticAnalyzer.generateTast(tast);
|
|
||||||
|
|
||||||
assertTrue(SemanticAnalyzer.errors.isEmpty());
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// ------------------ Helpers ------------------
|
// ------------------ Helpers ------------------
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -14,9 +14,6 @@ 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,441 +1,5 @@
|
|||||||
package semantic;
|
package semantic;
|
||||||
|
|
||||||
import ast.ASTNode;
|
|
||||||
import ast.ClassNode;
|
|
||||||
import ast.ProgramNode;
|
|
||||||
import ast.expressions.IExpressionNode;
|
|
||||||
import ast.expressions.unaryexpressions.MemberAccessNode;
|
|
||||||
import ast.expressions.unaryexpressions.UnaryNode;
|
|
||||||
import ast.members.ConstructorNode;
|
|
||||||
import ast.members.FieldNode;
|
|
||||||
import ast.members.MethodNode;
|
|
||||||
import ast.parameters.ParameterNode;
|
|
||||||
import ast.statementexpressions.AssignNode;
|
|
||||||
import ast.statementexpressions.AssignableNode;
|
|
||||||
import ast.statementexpressions.methodcallstatementnexpressions.MethodCallNode;
|
|
||||||
import ast.statements.BlockNode;
|
|
||||||
import ast.statements.ReturnNode;
|
|
||||||
import ast.type.AccessModifierNode;
|
|
||||||
import ast.type.EnumValueNode;
|
|
||||||
import ast.type.ValueNode;
|
|
||||||
import ast.type.type.BaseType;
|
|
||||||
import ast.type.type.TypeEnum;
|
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
|
||||||
import org.junit.jupiter.api.DisplayName;
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
import parser.Helper;
|
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
|
||||||
|
|
||||||
public class SemanticTest {
|
public class SemanticTest {
|
||||||
|
|
||||||
@BeforeEach
|
|
||||||
public void setUp() {
|
|
||||||
SemanticAnalyzer.clearAnalyzer();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
@DisplayName("Empty Class Test")
|
|
||||||
public void emptyClassTest() {
|
|
||||||
ClassNode emptyClass = Helper.generateEmptyClass("EmptyClass");
|
|
||||||
ProgramNode abstractSyntaxTree = new ProgramNode();
|
|
||||||
abstractSyntaxTree.addClass(emptyClass);
|
|
||||||
|
|
||||||
ASTNode typedAst = SemanticAnalyzer.generateTast(abstractSyntaxTree);
|
|
||||||
for (Exception runtimeException : SemanticAnalyzer.errors) {
|
|
||||||
runtimeException.printStackTrace();
|
|
||||||
}
|
|
||||||
assertTrue(SemanticAnalyzer.errors.isEmpty());
|
|
||||||
assertNotNull(typedAst);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Test
|
|
||||||
@DisplayName("Multiple Empty Classes Test")
|
|
||||||
public void multipleEmptyClassesTest() {
|
|
||||||
ClassNode class1 = Helper.generateEmptyClass("MultipleClasses");
|
|
||||||
ClassNode class2 = Helper.generateEmptyClass("TestClass2");
|
|
||||||
ProgramNode abstractSyntaxTree = new ProgramNode();
|
|
||||||
abstractSyntaxTree.addClass(class1);
|
|
||||||
abstractSyntaxTree.addClass(class2);
|
|
||||||
|
|
||||||
ASTNode typedAst = SemanticAnalyzer.generateTast(abstractSyntaxTree);
|
|
||||||
for (Exception runtimeException : SemanticAnalyzer.errors) {
|
|
||||||
runtimeException.printStackTrace();
|
|
||||||
}
|
|
||||||
assertTrue(SemanticAnalyzer.errors.isEmpty());
|
|
||||||
assertNotNull(typedAst);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Test
|
|
||||||
@DisplayName("Empty Class Test with Constructor")
|
|
||||||
public void emptyClassWithConstructorTest() {
|
|
||||||
ClassNode class1 = Helper.generateEmptyClass("EmptyClassWithConstructor");
|
|
||||||
ProgramNode abstractSyntaxTree = new ProgramNode();
|
|
||||||
abstractSyntaxTree.addClass(class1);
|
|
||||||
|
|
||||||
ASTNode typedAst = SemanticAnalyzer.generateTast(abstractSyntaxTree);
|
|
||||||
for (Exception runtimeException : SemanticAnalyzer.errors) {
|
|
||||||
runtimeException.printStackTrace();
|
|
||||||
}
|
|
||||||
assertTrue(SemanticAnalyzer.errors.isEmpty());
|
|
||||||
assertNotNull(typedAst);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
@DisplayName("Field Test")
|
|
||||||
public void fieldTest() {
|
|
||||||
ClassNode class1 = Helper.generateEmptyClass("Field");
|
|
||||||
class1.addMember(new FieldNode(new AccessModifierNode("public"), new BaseType(TypeEnum.INT), "a"));
|
|
||||||
|
|
||||||
ProgramNode abstractSyntaxTree = new ProgramNode();
|
|
||||||
abstractSyntaxTree.addClass(class1);
|
|
||||||
|
|
||||||
ASTNode typedAst = SemanticAnalyzer.generateTast(abstractSyntaxTree);
|
|
||||||
for (Exception runtimeException : SemanticAnalyzer.errors) {
|
|
||||||
runtimeException.printStackTrace();
|
|
||||||
}
|
|
||||||
assertTrue(SemanticAnalyzer.errors.isEmpty());
|
|
||||||
assertNotNull(typedAst);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
@DisplayName("Field Test with Accessmodifier")
|
|
||||||
public void fieldTestWithModifier() {
|
|
||||||
ClassNode class1 = Helper.generateEmptyClass("FieldWithAccessModifier");
|
|
||||||
class1.addMember(new FieldNode(new AccessModifierNode("public"), new BaseType(TypeEnum.INT), "a"));
|
|
||||||
|
|
||||||
ProgramNode abstractSyntaxTree = new ProgramNode();
|
|
||||||
abstractSyntaxTree.addClass(class1);
|
|
||||||
|
|
||||||
ASTNode typedAst = SemanticAnalyzer.generateTast(abstractSyntaxTree);
|
|
||||||
for (Exception runtimeException : SemanticAnalyzer.errors) {
|
|
||||||
runtimeException.printStackTrace();
|
|
||||||
}
|
|
||||||
assertTrue(SemanticAnalyzer.errors.isEmpty());
|
|
||||||
assertNotNull(typedAst);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
@DisplayName("Comments Ignore Test")
|
|
||||||
public void commentsIgnoreTest() {
|
|
||||||
ClassNode class1 = Helper.generateEmptyClass("Comments");
|
|
||||||
class1.addMember(new FieldNode(new AccessModifierNode("private"), new BaseType(TypeEnum.INT), "a"));
|
|
||||||
|
|
||||||
ProgramNode abstractSyntaxTree = new ProgramNode();
|
|
||||||
abstractSyntaxTree.addClass(class1);
|
|
||||||
|
|
||||||
ASTNode typedAst = SemanticAnalyzer.generateTast(abstractSyntaxTree);
|
|
||||||
for (Exception runtimeException : SemanticAnalyzer.errors) {
|
|
||||||
runtimeException.printStackTrace();
|
|
||||||
}
|
|
||||||
assertTrue(SemanticAnalyzer.errors.isEmpty());
|
|
||||||
assertNotNull(typedAst);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
@DisplayName("Constructor Parameter Test")
|
|
||||||
public void constructorParameterTest() {
|
|
||||||
BlockNode block = new BlockNode();
|
|
||||||
block.addStatement(new ReturnNode(null));
|
|
||||||
ConstructorNode constructor = new ConstructorNode("public", "ConstructorParameter", block);
|
|
||||||
constructor.addParameter(new ParameterNode(new BaseType(TypeEnum.INT), "a"));
|
|
||||||
constructor.addParameter(new ParameterNode(new BaseType(TypeEnum.INT), "b"));
|
|
||||||
|
|
||||||
ClassNode class1 = new ClassNode("public", "ConstructorParameter");
|
|
||||||
class1.addMember(constructor);
|
|
||||||
|
|
||||||
ProgramNode abstractSyntaxTree = new ProgramNode();
|
|
||||||
abstractSyntaxTree.addClass(class1);
|
|
||||||
|
|
||||||
ASTNode typedAst = SemanticAnalyzer.generateTast(abstractSyntaxTree);
|
|
||||||
for (Exception runtimeException : SemanticAnalyzer.errors) {
|
|
||||||
runtimeException.printStackTrace();
|
|
||||||
}
|
|
||||||
assertTrue(SemanticAnalyzer.errors.isEmpty());
|
|
||||||
assertNotNull(typedAst);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
@DisplayName("This Dot Test")
|
|
||||||
public void thisDotTest() {
|
|
||||||
BlockNode block = new BlockNode();
|
|
||||||
MemberAccessNode memberAccess = new MemberAccessNode(true);
|
|
||||||
memberAccess.addIdentifier("a");
|
|
||||||
|
|
||||||
AssignableNode assignable = new AssignableNode(memberAccess);
|
|
||||||
|
|
||||||
ValueNode value = new ValueNode(EnumValueNode.INT_VALUE, "1");
|
|
||||||
IExpressionNode expression = new UnaryNode(value);
|
|
||||||
|
|
||||||
block.addStatement(new AssignNode(assignable, expression));
|
|
||||||
block.addStatement(new ReturnNode(null));
|
|
||||||
ConstructorNode constructor = new ConstructorNode("public", "ThisDot", block);
|
|
||||||
|
|
||||||
ClassNode class1 = new ClassNode("public", "ThisDot");
|
|
||||||
class1.addMember(new FieldNode(new AccessModifierNode("public"), new BaseType(TypeEnum.INT), "a"));
|
|
||||||
class1.addMember(constructor);
|
|
||||||
|
|
||||||
ProgramNode abstractSyntaxTree = new ProgramNode();
|
|
||||||
abstractSyntaxTree.addClass(class1);
|
|
||||||
|
|
||||||
ASTNode typedAst = SemanticAnalyzer.generateTast(abstractSyntaxTree);
|
|
||||||
for (Exception runtimeException : SemanticAnalyzer.errors) {
|
|
||||||
runtimeException.printStackTrace();
|
|
||||||
}
|
|
||||||
assertTrue(SemanticAnalyzer.errors.isEmpty());
|
|
||||||
assertNotNull(typedAst);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
@DisplayName("Constructor This Dot Test")
|
|
||||||
public void constructorThisDotTest() {
|
|
||||||
BlockNode block = new BlockNode();
|
|
||||||
MemberAccessNode memberAccess = new MemberAccessNode(true);
|
|
||||||
memberAccess.addIdentifier("a");
|
|
||||||
|
|
||||||
AssignableNode assignable = new AssignableNode(memberAccess);
|
|
||||||
|
|
||||||
IExpressionNode expression = new UnaryNode("a");
|
|
||||||
|
|
||||||
block.addStatement(new AssignNode(assignable, expression));
|
|
||||||
block.addStatement(new ReturnNode(null));
|
|
||||||
ConstructorNode constructor = new ConstructorNode("public", "ConstructorThisDot", block);
|
|
||||||
constructor.addParameter(new ParameterNode(new BaseType(TypeEnum.INT), "a"));
|
|
||||||
|
|
||||||
ClassNode class1 = new ClassNode("public", "ConstructorThisDot");
|
|
||||||
class1.addMember(new FieldNode(new AccessModifierNode("private"), new BaseType(TypeEnum.INT), "a"));
|
|
||||||
class1.addMember(constructor);
|
|
||||||
|
|
||||||
ProgramNode abstractSyntaxTree = new ProgramNode();
|
|
||||||
abstractSyntaxTree.addClass(class1);
|
|
||||||
|
|
||||||
ASTNode typedAst = SemanticAnalyzer.generateTast(abstractSyntaxTree);
|
|
||||||
for (Exception runtimeException : SemanticAnalyzer.errors) {
|
|
||||||
runtimeException.printStackTrace();
|
|
||||||
}
|
|
||||||
assertTrue(SemanticAnalyzer.errors.isEmpty());
|
|
||||||
assertNotNull(typedAst);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
@DisplayName("Void Methoden Test")
|
|
||||||
public void voidMethodenTest() {
|
|
||||||
ClassNode class1 = Helper.generateEmptyClass("VoidMethod");
|
|
||||||
BlockNode block = new BlockNode();
|
|
||||||
block.addStatement(new ReturnNode(null));
|
|
||||||
class1.addMember(new MethodNode("public", null, true, "test", block));
|
|
||||||
|
|
||||||
ProgramNode abstractSyntaxTree = new ProgramNode();
|
|
||||||
abstractSyntaxTree.addClass(class1);
|
|
||||||
|
|
||||||
ASTNode typedAst = SemanticAnalyzer.generateTast(abstractSyntaxTree);
|
|
||||||
for (Exception runtimeException : SemanticAnalyzer.errors) {
|
|
||||||
runtimeException.printStackTrace();
|
|
||||||
}
|
|
||||||
assertTrue(SemanticAnalyzer.errors.isEmpty());
|
|
||||||
assertNotNull(typedAst);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
@DisplayName("Constructor Method call Test")
|
|
||||||
public void constructorMethodCallTest() {
|
|
||||||
BlockNode blockCon = new BlockNode();
|
|
||||||
MemberAccessNode memberAccess = new MemberAccessNode(true);
|
|
||||||
memberAccess.addIdentifier("a");
|
|
||||||
|
|
||||||
AssignableNode assignable = new AssignableNode(memberAccess);
|
|
||||||
|
|
||||||
IExpressionNode expression = new UnaryNode(new MethodCallNode(null, "testMethod"));
|
|
||||||
|
|
||||||
blockCon.addStatement(new AssignNode(assignable, expression));
|
|
||||||
blockCon.addStatement(new ReturnNode(null));
|
|
||||||
ConstructorNode constructor = new ConstructorNode("public", "ConstructorMethodCall", blockCon);
|
|
||||||
|
|
||||||
BlockNode blockMethod = new BlockNode();
|
|
||||||
blockMethod.addStatement(new ReturnNode(new UnaryNode(new ValueNode(EnumValueNode.INT_VALUE, "1"))));
|
|
||||||
MethodNode method = new MethodNode("public", new BaseType(TypeEnum.INT), false, "testMethod", blockMethod);
|
|
||||||
|
|
||||||
ClassNode class1 = new ClassNode("public", "ConstructorMethodCall");
|
|
||||||
class1.addMember(new FieldNode(new AccessModifierNode("public"), new BaseType(TypeEnum.INT), "a"));
|
|
||||||
class1.addMember(constructor);
|
|
||||||
class1.addMember(method);
|
|
||||||
|
|
||||||
ProgramNode abstractSyntaxTree = new ProgramNode();
|
|
||||||
abstractSyntaxTree.addClass(class1);
|
|
||||||
|
|
||||||
ASTNode typedAst = SemanticAnalyzer.generateTast(abstractSyntaxTree);
|
|
||||||
for (Exception runtimeException : SemanticAnalyzer.errors) {
|
|
||||||
runtimeException.printStackTrace();
|
|
||||||
}
|
|
||||||
assertTrue(SemanticAnalyzer.errors.isEmpty());
|
|
||||||
assertNotNull(typedAst);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
@DisplayName("Constructor Method call Parameters Test")
|
|
||||||
public void constructorMethodCallParametersTest() {
|
|
||||||
BlockNode blockCon = new BlockNode();
|
|
||||||
MemberAccessNode memberAccess = new MemberAccessNode(true);
|
|
||||||
memberAccess.addIdentifier("a");
|
|
||||||
|
|
||||||
AssignableNode assignable = new AssignableNode(memberAccess);
|
|
||||||
|
|
||||||
MethodCallNode methodCall = new MethodCallNode(null, "testMethod");
|
|
||||||
methodCall.addExpression(new UnaryNode("a"));
|
|
||||||
IExpressionNode expression = new UnaryNode(methodCall);
|
|
||||||
|
|
||||||
blockCon.addStatement(new AssignNode(assignable, expression));
|
|
||||||
blockCon.addStatement(new ReturnNode(null));
|
|
||||||
ConstructorNode constructor = new ConstructorNode("public", "ConstructorMethodCallParameters", blockCon);
|
|
||||||
constructor.addParameter(new ParameterNode(new BaseType(TypeEnum.INT), "a"));
|
|
||||||
|
|
||||||
BlockNode blockMethod = new BlockNode();
|
|
||||||
blockMethod.addStatement(new ReturnNode(new UnaryNode("a")));
|
|
||||||
MethodNode method = new MethodNode("public", new BaseType(TypeEnum.INT), false, "testMethod", blockMethod);
|
|
||||||
method.addParameter(new ParameterNode(new BaseType(TypeEnum.INT), "a"));
|
|
||||||
|
|
||||||
ClassNode class1 = new ClassNode("public", "ConstructorMethodCallParameters");
|
|
||||||
class1.addMember(new FieldNode(new AccessModifierNode("public"), new BaseType(TypeEnum.INT), "a"));
|
|
||||||
class1.addMember(constructor);
|
|
||||||
class1.addMember(method);
|
|
||||||
|
|
||||||
ProgramNode abstractSyntaxTree = new ProgramNode();
|
|
||||||
abstractSyntaxTree.addClass(class1);
|
|
||||||
|
|
||||||
ASTNode typedAst = SemanticAnalyzer.generateTast(abstractSyntaxTree);
|
|
||||||
for (Exception runtimeException : SemanticAnalyzer.errors) {
|
|
||||||
runtimeException.printStackTrace();
|
|
||||||
}
|
|
||||||
assertTrue(SemanticAnalyzer.errors.isEmpty());
|
|
||||||
assertNotNull(typedAst);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
@DisplayName("Char Test")
|
|
||||||
public void charTest() {
|
|
||||||
BlockNode blockCon = new BlockNode();
|
|
||||||
MemberAccessNode memberAccess = new MemberAccessNode(true);
|
|
||||||
memberAccess.addIdentifier("a");
|
|
||||||
|
|
||||||
AssignableNode assignable = new AssignableNode(memberAccess);
|
|
||||||
|
|
||||||
MethodCallNode methodCall = new MethodCallNode(null, "testMethod");
|
|
||||||
methodCall.addExpression(new UnaryNode("a"));
|
|
||||||
IExpressionNode expression = new UnaryNode(methodCall);
|
|
||||||
|
|
||||||
blockCon.addStatement(new AssignNode(assignable, expression));
|
|
||||||
blockCon.addStatement(new ReturnNode(null));
|
|
||||||
ConstructorNode constructor = new ConstructorNode("public", "Char", blockCon);
|
|
||||||
constructor.addParameter(new ParameterNode(new BaseType(TypeEnum.CHAR), "a"));
|
|
||||||
|
|
||||||
BlockNode blockMethod = new BlockNode();
|
|
||||||
blockMethod.addStatement(new ReturnNode(new UnaryNode("a")));
|
|
||||||
MethodNode method = new MethodNode("public", new BaseType(TypeEnum.CHAR), false, "testMethod", blockMethod);
|
|
||||||
method.addParameter(new ParameterNode(new BaseType(TypeEnum.CHAR), "a"));
|
|
||||||
|
|
||||||
ClassNode class1 = new ClassNode("public", "Char");
|
|
||||||
class1.addMember(new FieldNode(new AccessModifierNode("public"), new BaseType(TypeEnum.CHAR), "a"));
|
|
||||||
class1.addMember(constructor);
|
|
||||||
class1.addMember(method);
|
|
||||||
|
|
||||||
ProgramNode abstractSyntaxTree = new ProgramNode();
|
|
||||||
abstractSyntaxTree.addClass(class1);
|
|
||||||
|
|
||||||
ASTNode typedAst = SemanticAnalyzer.generateTast(abstractSyntaxTree);
|
|
||||||
for (Exception runtimeException : SemanticAnalyzer.errors) {
|
|
||||||
runtimeException.printStackTrace();
|
|
||||||
}
|
|
||||||
assertTrue(SemanticAnalyzer.errors.isEmpty());
|
|
||||||
assertNotNull(typedAst);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
@DisplayName("Null Test")
|
|
||||||
public void nullTest() {
|
|
||||||
BlockNode blockCon = new BlockNode();
|
|
||||||
MemberAccessNode memberAccess = new MemberAccessNode(true);
|
|
||||||
memberAccess.addIdentifier("a");
|
|
||||||
|
|
||||||
AssignableNode assignable = new AssignableNode(memberAccess);
|
|
||||||
|
|
||||||
blockCon.addStatement(new AssignNode(assignable, new UnaryNode(new ValueNode(EnumValueNode.NULL_VALUE, "null"))));
|
|
||||||
blockCon.addStatement(new ReturnNode(null));
|
|
||||||
ConstructorNode constructor = new ConstructorNode("public", "Null", blockCon);
|
|
||||||
|
|
||||||
ClassNode class1 = new ClassNode("public", "Null");
|
|
||||||
class1.addMember(new FieldNode(new AccessModifierNode("public"), new BaseType(TypeEnum.INT), "a"));
|
|
||||||
class1.addMember(constructor);
|
|
||||||
|
|
||||||
ProgramNode abstractSyntaxTree = new ProgramNode();
|
|
||||||
abstractSyntaxTree.addClass(class1);
|
|
||||||
|
|
||||||
ASTNode typedAst = SemanticAnalyzer.generateTast(abstractSyntaxTree);
|
|
||||||
for (Exception runtimeException : SemanticAnalyzer.errors) {
|
|
||||||
runtimeException.printStackTrace();
|
|
||||||
}
|
|
||||||
assertTrue(SemanticAnalyzer.errors.isEmpty());
|
|
||||||
assertNotNull(typedAst);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
@DisplayName("Self Reference Test")
|
|
||||||
public void selfReferenceTest() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
@DisplayName("Variable Compare Test")
|
|
||||||
public void variableCompareTest() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
@DisplayName("Variable Calculation Test")
|
|
||||||
public void variableCalculationTest() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
@DisplayName("Main Method Test")
|
|
||||||
public void mainMethodTest() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
@DisplayName("While Test")
|
|
||||||
public void whileTest() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
@DisplayName("Do While Test")
|
|
||||||
public void doWhileTest() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
@DisplayName("For Test")
|
|
||||||
public void forTest() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
@DisplayName("Increment Test")
|
|
||||||
public void incrementTest() {
|
|
||||||
ClassNode classNode = Helper.generateEmptyClass("Increment");
|
|
||||||
classNode.addMember(new FieldNode(new AccessModifierNode("public"), new BaseType(TypeEnum.INT), "a"));
|
|
||||||
|
|
||||||
ProgramNode abstractSyntaxTree = new ProgramNode();
|
|
||||||
abstractSyntaxTree.addClass(classNode);
|
|
||||||
|
|
||||||
ASTNode typedAst = SemanticAnalyzer.generateTast(abstractSyntaxTree);
|
|
||||||
for (Exception runtimeException : SemanticAnalyzer.errors) {
|
|
||||||
runtimeException.printStackTrace();
|
|
||||||
}
|
|
||||||
assertTrue(SemanticAnalyzer.errors.isEmpty());
|
|
||||||
assertNotNull(typedAst);
|
|
||||||
}
|
|
||||||
}
|
}
|
@ -1,25 +0,0 @@
|
|||||||
public class Main {
|
|
||||||
public static void main(String[] args) {
|
|
||||||
Car myCar = new Car(2020);
|
|
||||||
int tires = 0;
|
|
||||||
int year = myCar.getYear();
|
|
||||||
|
|
||||||
if (year == 2020) {
|
|
||||||
tires = 4;
|
|
||||||
} else {
|
|
||||||
tires = 2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class Car {
|
|
||||||
private int year;
|
|
||||||
|
|
||||||
public Car(int year) {
|
|
||||||
this.year = year;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getYear() {
|
|
||||||
return this.year;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,36 +0,0 @@
|
|||||||
public class ControlStructures {
|
|
||||||
|
|
||||||
public int sum(int a, int b) {
|
|
||||||
return a + b;
|
|
||||||
}
|
|
||||||
|
|
||||||
public cahr checkNumber(int num) {
|
|
||||||
if (num > 0) {
|
|
||||||
return "p";
|
|
||||||
} else if (num < 0) {
|
|
||||||
return "n";
|
|
||||||
} else {
|
|
||||||
return "z";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void printNumbersUpTo(int limit) {
|
|
||||||
int even = 0;
|
|
||||||
int uneven = 0;
|
|
||||||
int i = 0;
|
|
||||||
while (i < limit) {
|
|
||||||
if (i % 2 == 0) {
|
|
||||||
even++;
|
|
||||||
} else {
|
|
||||||
uneven = uneven + 1;
|
|
||||||
}
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void main(String[] args) {
|
|
||||||
ControlStructures cs = new ControlStructures();
|
|
||||||
cs.printNumbersUpTo(5);
|
|
||||||
int result = cs.sum(5, 5);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,11 +0,0 @@
|
|||||||
public class Person {
|
|
||||||
private int age;
|
|
||||||
|
|
||||||
public Person(int age) {
|
|
||||||
this.age = age;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getAge() {
|
|
||||||
return this.age;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,10 +0,0 @@
|
|||||||
class VariableCompare{
|
|
||||||
|
|
||||||
void trueMethod(boolean a, int c) {
|
|
||||||
if(a && c == 10){
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
@ -1,22 +0,0 @@
|
|||||||
// @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;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,34 +0,0 @@
|
|||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,30 +0,0 @@
|
|||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,3 +1,4 @@
|
|||||||
|
// @expected: TypeMismatchException
|
||||||
public class Test{
|
public class Test{
|
||||||
|
|
||||||
public void test(int x){
|
public void test(int x){
|
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue
Block a user