Compare commits
3 Commits
ceb1231632
...
chainedMet
Author | SHA1 | Date | |
---|---|---|---|
|
1ffcd79265 | ||
|
5cd1ec2d05 | ||
|
49195c754c |
6
.gitignore
vendored
6
.gitignore
vendored
@@ -77,10 +77,10 @@ fabric.properties
|
|||||||
.idea/caches/build_file_checksums.ser
|
.idea/caches/build_file_checksums.ser
|
||||||
|
|
||||||
/target
|
/target
|
||||||
src/main/resources/logs/miniCompilerLog.log
|
src/main/resources/logs/RaupenLog.log
|
||||||
src/main/resources/output/CompilerInput.class
|
src/main/resources/output/CompilerInput.class
|
||||||
src/test/resources/output/javac/CompilerInput$Test.class
|
src/test/resources/output/javac/CompilerInput$Test.class
|
||||||
src/test/resources/output/javac/CompilerInput.class
|
src/test/resources/output/javac/CompilerInput.class
|
||||||
src/test/resources/output/miniCompiler/CompilerInput.class
|
src/test/resources/output/raupenpiler/CompilerInput.class
|
||||||
src/test/resources/output/miniCompiler/CompilerInput$Test.class
|
src/test/resources/output/raupenpiler/CompilerInput$Test.class
|
||||||
.idea/inspectionProfiles/Project_Default.xml
|
.idea/inspectionProfiles/Project_Default.xml
|
||||||
|
@@ -1,58 +0,0 @@
|
|||||||
# Kurzdokumentation
|
|
||||||
|
|
||||||
## Aufgabenverteilung
|
|
||||||
|
|
||||||
### Maximilian Stahl und Jannik Rombach:
|
|
||||||
- **Scanner**
|
|
||||||
- **Parser**
|
|
||||||
- **AST**
|
|
||||||
- **AstBuilder**
|
|
||||||
- **Modul: ast**
|
|
||||||
- Alle
|
|
||||||
- **Modul: parser**
|
|
||||||
- Alle
|
|
||||||
- **Modul: visitor**
|
|
||||||
- Alle
|
|
||||||
- **Testmodul: parser**
|
|
||||||
- AstBuildertest.java
|
|
||||||
- Helper.java
|
|
||||||
- **Testfiles: singleFeatureTests**
|
|
||||||
- Alle
|
|
||||||
|
|
||||||
### Johannes Ehlert:
|
|
||||||
- **Semantische Analyse**
|
|
||||||
- **Modul: semantic**
|
|
||||||
- **Modul: typecheck**
|
|
||||||
- **Testmodul: parser**
|
|
||||||
- AstBuildertest.java
|
|
||||||
- **Testfiles: typedAstFeatureTests**
|
|
||||||
- Großteil
|
|
||||||
- **Testfiles: typedAstExceptionsTests**
|
|
||||||
- Großteil
|
|
||||||
|
|
||||||
### David Große:
|
|
||||||
- **Bytecodegenerator**
|
|
||||||
- **Modul: bytecode**
|
|
||||||
- Alle
|
|
||||||
|
|
||||||
### Lucas Janker:
|
|
||||||
- **Tests**
|
|
||||||
- **Modul: main**
|
|
||||||
- Alle
|
|
||||||
- **Testmodul: main**
|
|
||||||
- Alle
|
|
||||||
- **Testmodul: parser**
|
|
||||||
- ScannerTest.java
|
|
||||||
- ParserTest.java
|
|
||||||
- **Testmodul: semantic**
|
|
||||||
- **Testfiles: combinedFeatureTests**
|
|
||||||
- Alle
|
|
||||||
- **Testfiles: failureTests**
|
|
||||||
- Alle
|
|
||||||
- **Testfiles: Alle**
|
|
||||||
- Refactoring
|
|
||||||
- **Ordnerstrukturen**
|
|
||||||
- Großteil
|
|
||||||
- **Build**
|
|
||||||
- **Makefile**
|
|
||||||
- **Dokumentation**
|
|
104
README.md
104
README.md
@@ -1,104 +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/ -> Running E2E tests
|
|
||||||
│ ├── parser/ -> Performs tests on the parser
|
|
||||||
│ ├── semantic/ -> Performs tests on the semantic check
|
|
||||||
└── resources/ -> Ressources for running the Tests
|
|
||||||
```
|
|
||||||
|
|
||||||
## Class-Diagramm AST
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
## Distribution of the realisation
|
|
||||||
|
|
||||||
### i22030 & i22035
|
|
||||||
|
|
||||||
Parser:
|
|
||||||
- Grammar -> (src/main/java/parser/grammar)
|
|
||||||
- Scanner
|
|
||||||
- Parser
|
|
||||||
- Abstract Syntax Tree (AST) -> (src/main/java/ast)
|
|
||||||
- AstBuilder -> (src/main/java/parser/astBuilder)
|
|
||||||
|
|
||||||
Parser tests:
|
|
||||||
- ParserTests -> (src/test/java/parser)
|
|
||||||
- TestCases -> (src/test/resources/input/singeFeatureTests)
|
|
||||||
|
|
||||||
Other:
|
|
||||||
- Documentation -> (README.md)
|
|
||||||
- Ast Class-Diagramm -> (ast.png)
|
|
||||||
- PowerPoint
|
|
||||||
|
|
||||||
### i22005
|
|
||||||
Semantic check:
|
|
||||||
- Set all types and check whether types have been used correctly
|
|
||||||
- Contexts -> (src/main/java/semantic/context)
|
|
||||||
- Exceptions Handling -> (src/main/java/semantic/exceptions)
|
|
||||||
|
|
||||||
Semantic Tests:
|
|
||||||
- Typing and Type checking -> (src/test/java/semantic/EndToTypedAstTest)
|
|
||||||
- Exception and feature test -> (src/test/resources/input/typedAstExceptionsTests)
|
|
||||||
|
|
||||||
### i22007
|
|
||||||
Bytecode generation:
|
|
||||||
- Complete bytecode generation -> (src/mein/java/bytecode)
|
|
||||||
|
|
||||||
### i22011
|
|
||||||
Tests and execution:
|
|
||||||
- Makefile
|
|
||||||
- Running Compiler -> (src/main/main)
|
|
||||||
- Running E2E tests -> (src/test/main)
|
|
||||||
- Typing and Type checking -> (src/test/java/semantic/EndToTypedAstTest)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## 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.
|
|
31
pom.xml
31
pom.xml
@@ -20,25 +20,7 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.junit.jupiter</groupId>
|
<groupId>org.junit.jupiter</groupId>
|
||||||
<artifactId>junit-jupiter-engine</artifactId>
|
<artifactId>junit-jupiter-engine</artifactId>
|
||||||
<version>5.11.0-M2</version>
|
<version>5.9.3</version> <!-- Change the version as needed -->
|
||||||
<scope>test</scope>
|
|
||||||
</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>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
@@ -62,6 +44,12 @@
|
|||||||
<version>3.26.0</version>
|
<version>3.26.0</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</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 +59,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>
|
||||||
|
143
readme.md
143
readme.md
@@ -1,143 +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 Stuttgart (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/ -> Running E2E tests
|
|
||||||
│ ├── parser/ -> Performs tests on the parser
|
|
||||||
│ ├── semantic/ -> Performs tests on the semantic check
|
|
||||||
└── resources/ -> Ressources for running the Tests
|
|
||||||
```
|
|
||||||
|
|
||||||
## Class-Diagramm AST
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
## Distribution of the realisation
|
|
||||||
|
|
||||||
### i22030 & i22035
|
|
||||||
|
|
||||||
Parser:
|
|
||||||
- Grammar -> (src/main/java/parser/grammar)
|
|
||||||
- Scanner
|
|
||||||
- Parser
|
|
||||||
- Abstract Syntax Tree (AST) -> (src/main/java/ast)
|
|
||||||
- AstBuilder -> (src/main/java/parser/astBuilder)
|
|
||||||
|
|
||||||
Parser tests:
|
|
||||||
- ParserTests -> (src/test/java/parser)
|
|
||||||
- TestCases -> (src/test/resources/input/singeFeatureTests)
|
|
||||||
|
|
||||||
Other:
|
|
||||||
- Documentation -> (README.md)
|
|
||||||
- Ast Class-Diagramm -> (ast.png)
|
|
||||||
- PowerPoint
|
|
||||||
|
|
||||||
### i22005
|
|
||||||
Semantic check:
|
|
||||||
- Set all types and check whether types have been used correctly
|
|
||||||
- Contexts -> (src/main/java/semantic/context)
|
|
||||||
- Exceptions Handling -> (src/main/java/semantic/exceptions)
|
|
||||||
|
|
||||||
Semantic Tests:
|
|
||||||
- Typing and Type checking -> (src/test/java/semantic/EndToTypedAstTest)
|
|
||||||
- Exception and feature test -> (src/test/resources/input/typedAstExceptionsTests)
|
|
||||||
|
|
||||||
### i22007
|
|
||||||
Bytecode generation:
|
|
||||||
- Complete bytecode generation -> (src/mein/java/bytecode)
|
|
||||||
|
|
||||||
### i22011
|
|
||||||
Tests and execution:
|
|
||||||
- Makefile
|
|
||||||
- Running Compiler -> (src/main/main)
|
|
||||||
- Running E2E tests -> (src/test/main)
|
|
||||||
- Typing and Type checking -> (src/test/java/semantic/EndToTypedAstTest)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## 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
|
|
||||||
### Possibilities
|
|
||||||
### 1. Start miniCompiler using make:
|
|
||||||
Make needs to be installed
|
|
||||||
```bash
|
|
||||||
cd .\src\test\ ; make clean compile-miniCompiler
|
|
||||||
```
|
|
||||||
|
|
||||||
### 2. Start miniCompiler using jar:
|
|
||||||
If you do not have the .jar, download it [here](https://gitea.hb.dhbw-stuttgart.de/i22005/NichtHaskell2.0/src/branch/Endabgabe/src) or compile it using mvn package or make first
|
|
||||||
```
|
|
||||||
java.exe -DgenJar=bool -DgenClass=bool -jar path_to_jar\jarName.jar 'path_to_input_file.java' 'path_to_output_directory'
|
|
||||||
```
|
|
||||||
|
|
||||||
Example (jar needs to be in the target directory)
|
|
||||||
```bash
|
|
||||||
java.exe -DgenJar=true -DgenClass=true -jar .\target\JavaCompiler-1.0-jar-with-dependencies.jar 'src/main/resources/input/CompilerInput.java' 'src/main/resources/output'
|
|
||||||
```
|
|
||||||
|
|
||||||
- set DgenJar true, to generate the jar, false for no jar
|
|
||||||
|
|
||||||
```
|
|
||||||
DgenJar=true
|
|
||||||
```
|
|
||||||
|
|
||||||
- set DgenClass true, to generate class files, false for no class files
|
|
||||||
|
|
||||||
```
|
|
||||||
DgenClass=true
|
|
||||||
```
|
|
||||||
|
|
||||||
## How to run tests
|
|
||||||
|
|
||||||
```bash
|
|
||||||
mvn test
|
|
||||||
```
|
|
||||||
Or start them manually in your IDE
|
|
@@ -1,6 +1,20 @@
|
|||||||
package ast;
|
package ast;
|
||||||
|
|
||||||
|
import bytecode.visitor.ClassVisitor;
|
||||||
|
import semantic.SemanticVisitor;
|
||||||
|
import typechecker.TypeCheckResult;
|
||||||
|
|
||||||
public interface ASTNode {
|
public interface ASTNode {
|
||||||
|
|
||||||
|
//Todo: @BruderJohn & @i22007 Interface anwenden + geeignetetn Methodename.
|
||||||
|
|
||||||
|
/*
|
||||||
|
Typecheck:
|
||||||
|
public TypeCheckResult acceptType(SemanticVisitor visitor);
|
||||||
|
|
||||||
|
Bytecode:
|
||||||
|
public void accepByteCode(ClassVisitor classVisitor);
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -1,11 +1,12 @@
|
|||||||
package ast;
|
package ast;
|
||||||
|
|
||||||
import ast.type.AccessModifierNode;
|
import ast.type.AccessModifierNode;
|
||||||
|
import ast.members.ConstructorNode;
|
||||||
import ast.members.MemberNode;
|
import ast.members.MemberNode;
|
||||||
import ast.members.MethodNode;
|
import ast.members.MethodNode;
|
||||||
import bytecode.visitor.ClassVisitor;
|
import bytecode.visitor.ClassVisitor;
|
||||||
import semantic.SemanticVisitor;
|
import semantic.SemanticVisitor;
|
||||||
import semantic.TypeCheckResult;
|
import typechecker.TypeCheckResult;
|
||||||
import visitor.Visitable;
|
import visitor.Visitable;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
@@ -2,7 +2,7 @@ package ast;
|
|||||||
|
|
||||||
import bytecode.visitor.ProgramVisitor;
|
import bytecode.visitor.ProgramVisitor;
|
||||||
import semantic.SemanticVisitor;
|
import semantic.SemanticVisitor;
|
||||||
import semantic.TypeCheckResult;
|
import typechecker.TypeCheckResult;
|
||||||
import visitor.Visitable;
|
import visitor.Visitable;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
@@ -4,12 +4,12 @@ import ast.expressions.IExpressionNode;
|
|||||||
import ast.type.type.*;
|
import ast.type.type.*;
|
||||||
import bytecode.visitor.MethodVisitor;
|
import bytecode.visitor.MethodVisitor;
|
||||||
import semantic.SemanticVisitor;
|
import semantic.SemanticVisitor;
|
||||||
import semantic.TypeCheckResult;
|
import typechecker.TypeCheckResult;
|
||||||
import visitor.Visitable;
|
import visitor.Visitable;
|
||||||
|
|
||||||
public class BinaryNode implements IExpressionNode, Visitable {
|
public class BinaryNode implements IExpressionNode, Visitable {
|
||||||
|
|
||||||
public ITypeNode typeNode;
|
private ITypeNode typeNode;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TypeCheckResult accept(SemanticVisitor visitor) {
|
public TypeCheckResult accept(SemanticVisitor visitor) {
|
||||||
|
@@ -1,13 +1,15 @@
|
|||||||
package ast.expressions.binaryexpressions;
|
package ast.expressions.binaryexpressions;
|
||||||
|
|
||||||
|
import ast.type.type.*;
|
||||||
import bytecode.visitor.MethodVisitor;
|
import bytecode.visitor.MethodVisitor;
|
||||||
import semantic.SemanticVisitor;
|
import semantic.SemanticVisitor;
|
||||||
import semantic.TypeCheckResult;
|
import typechecker.TypeCheckResult;
|
||||||
|
|
||||||
public class CalculationNode extends BinaryNode {
|
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;
|
||||||
@@ -19,7 +21,7 @@ public class CalculationNode extends BinaryNode {
|
|||||||
this.dotExpression = dotExpression;
|
this.dotExpression = dotExpression;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setOperator(String operator) {
|
private void setOperator(String operator) {
|
||||||
if(operator != null) {
|
if(operator != null) {
|
||||||
if(operator.equals("+")) {
|
if(operator.equals("+")) {
|
||||||
this.operator = EnumLineOperator.PLUS;
|
this.operator = EnumLineOperator.PLUS;
|
||||||
|
@@ -2,28 +2,30 @@ package ast.expressions.binaryexpressions;
|
|||||||
|
|
||||||
import bytecode.visitor.MethodVisitor;
|
import bytecode.visitor.MethodVisitor;
|
||||||
import semantic.SemanticVisitor;
|
import semantic.SemanticVisitor;
|
||||||
import semantic.TypeCheckResult;
|
import typechecker.TypeCheckResult;
|
||||||
|
|
||||||
public class DotNode extends BinaryNode {
|
public class DotNode extends BinaryNode {
|
||||||
public DotNode dotExpression;
|
public DotNode dotExpression;
|
||||||
public EnumDotOperator operator;
|
public EnumDotOperator operator;
|
||||||
public DotSubtractionNode dotSubtractionExpression;
|
public DotSubstractionNode dotSubstractionExpression;
|
||||||
|
|
||||||
public DotNode(DotNode dotExpression, String operator, DotSubtractionNode dotSubtractionExpression) {
|
public DotNode(DotNode dotExpression, String operator, DotSubstractionNode dotSubstractionExpression) {
|
||||||
this.dotExpression = dotExpression;
|
this.dotExpression = dotExpression;
|
||||||
setOperator(operator);
|
setOperator(operator);
|
||||||
this.dotSubtractionExpression = dotSubtractionExpression;
|
this.dotSubstractionExpression = dotSubstractionExpression;
|
||||||
}
|
}
|
||||||
|
|
||||||
public DotNode(DotSubtractionNode dotSubtractionExpression) {
|
public DotNode(DotSubstractionNode dotSubstractionExpression) {
|
||||||
this.dotSubtractionExpression = dotSubtractionExpression;
|
this.dotSubstractionExpression = dotSubstractionExpression;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setOperator(String operator) {
|
private void setOperator(String operator) {
|
||||||
switch (operator) {
|
if(operator.equals("*")) {
|
||||||
case "*" -> this.operator = EnumDotOperator.MULT;
|
this.operator = EnumDotOperator.MULT;
|
||||||
case "/" -> this.operator = EnumDotOperator.DIV;
|
} else if(operator.equals("/")) {
|
||||||
case "%" -> this.operator = EnumDotOperator.MOD;
|
this.operator = EnumDotOperator.DIV;
|
||||||
|
} else if(operator.equals("%")) {
|
||||||
|
this.operator = EnumDotOperator.MOD;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -2,31 +2,32 @@ package ast.expressions.binaryexpressions;
|
|||||||
|
|
||||||
import ast.expressions.unaryexpressions.MemberAccessNode;
|
import ast.expressions.unaryexpressions.MemberAccessNode;
|
||||||
import ast.statementexpressions.methodcallstatementnexpressions.MethodCallNode;
|
import ast.statementexpressions.methodcallstatementnexpressions.MethodCallNode;
|
||||||
|
import ast.type.type.*;
|
||||||
import ast.type.ValueNode;
|
import ast.type.ValueNode;
|
||||||
import bytecode.visitor.MethodVisitor;
|
import bytecode.visitor.MethodVisitor;
|
||||||
import semantic.SemanticVisitor;
|
import semantic.SemanticVisitor;
|
||||||
import semantic.TypeCheckResult;
|
import typechecker.TypeCheckResult;
|
||||||
|
|
||||||
public class DotSubtractionNode extends BinaryNode {
|
public class DotSubstractionNode extends BinaryNode {
|
||||||
public ValueNode value;
|
public ValueNode value;
|
||||||
public String identifier;
|
public String identifier;
|
||||||
public MemberAccessNode memberAccess;
|
public MemberAccessNode memberAccess;
|
||||||
public MethodCallNode methodCall;
|
public MethodCallNode methodCall;
|
||||||
public CalculationNode calculationExpression;
|
public CalculationNode calculationExpression;
|
||||||
|
|
||||||
public DotSubtractionNode(ValueNode value) {
|
public DotSubstractionNode(ValueNode value) {
|
||||||
this.value = value;
|
this.value = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public DotSubtractionNode(String identifier) {
|
public DotSubstractionNode(String identifier) {
|
||||||
this.identifier = identifier;
|
this.identifier = identifier;
|
||||||
}
|
}
|
||||||
|
|
||||||
public DotSubtractionNode(MemberAccessNode memberAccess) {
|
public DotSubstractionNode(MemberAccessNode memberAccess) {
|
||||||
this.memberAccess = memberAccess;
|
this.memberAccess = memberAccess;
|
||||||
}
|
}
|
||||||
|
|
||||||
public DotSubtractionNode(MethodCallNode methodCall, CalculationNode calculationExpression) {
|
public DotSubstractionNode(MethodCallNode methodCall, CalculationNode calculationExpression) {
|
||||||
this.methodCall = methodCall;
|
this.methodCall = methodCall;
|
||||||
this.calculationExpression = calculationExpression;
|
this.calculationExpression = calculationExpression;
|
||||||
}
|
}
|
@@ -2,9 +2,10 @@ package ast.expressions.binaryexpressions;
|
|||||||
|
|
||||||
import ast.expressions.IExpressionNode;
|
import ast.expressions.IExpressionNode;
|
||||||
import ast.expressions.unaryexpressions.UnaryNode;
|
import ast.expressions.unaryexpressions.UnaryNode;
|
||||||
|
import ast.type.type.*;
|
||||||
import bytecode.visitor.MethodVisitor;
|
import bytecode.visitor.MethodVisitor;
|
||||||
import semantic.SemanticVisitor;
|
import semantic.SemanticVisitor;
|
||||||
import semantic.TypeCheckResult;
|
import typechecker.TypeCheckResult;
|
||||||
|
|
||||||
public class NonCalculationNode extends BinaryNode {
|
public class NonCalculationNode extends BinaryNode {
|
||||||
public UnaryNode unaryExpression;
|
public UnaryNode unaryExpression;
|
||||||
@@ -17,16 +18,23 @@ public class NonCalculationNode extends BinaryNode {
|
|||||||
this.expression = expression;
|
this.expression = expression;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setOperator(String operator) {
|
private void setOperator(String operator) {
|
||||||
switch (operator) {
|
if(operator.equals("&&")) {
|
||||||
case "&&" -> this.operator = EnumNonCalculationOperator.AND;
|
this.operator = EnumNonCalculationOperator.AND;
|
||||||
case "||" -> this.operator = EnumNonCalculationOperator.OR;
|
} else if(operator.equals("||")) {
|
||||||
case ">" -> this.operator = EnumNonCalculationOperator.GREATER;
|
this.operator = EnumNonCalculationOperator.OR;
|
||||||
case "<" -> this.operator = EnumNonCalculationOperator.LESS;
|
} else if(operator.equals(">")) {
|
||||||
case ">=" -> this.operator = EnumNonCalculationOperator.GREATER_EQUAL;
|
this.operator = EnumNonCalculationOperator.GREATER;
|
||||||
case "<=" -> this.operator = EnumNonCalculationOperator.LESS_EQUAL;
|
} else if(operator.equals("<")) {
|
||||||
case "==" -> this.operator = EnumNonCalculationOperator.EQUAL;
|
this.operator = EnumNonCalculationOperator.LESS;
|
||||||
case "!=" -> this.operator = EnumNonCalculationOperator.NOT_EQUAL;
|
} else if(operator.equals(">=")) {
|
||||||
|
this.operator = EnumNonCalculationOperator.GREATER_EQUAL;
|
||||||
|
} else if(operator.equals("<=")) {
|
||||||
|
this.operator = EnumNonCalculationOperator.LESS_EQUAL;
|
||||||
|
} else if(operator.equals("==")) {
|
||||||
|
this.operator = EnumNonCalculationOperator.EQUAL;
|
||||||
|
} else if(operator.equals("!=")) {
|
||||||
|
this.operator = EnumNonCalculationOperator.NOT_EQUAL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -2,9 +2,9 @@ package ast.expressions.unaryexpressions;
|
|||||||
|
|
||||||
import ast.ASTNode;
|
import ast.ASTNode;
|
||||||
import bytecode.visitor.MethodVisitor;
|
import bytecode.visitor.MethodVisitor;
|
||||||
|
import ast.type.type.ITypeNode;
|
||||||
import semantic.SemanticVisitor;
|
import semantic.SemanticVisitor;
|
||||||
import semantic.TypeCheckResult;
|
import typechecker.TypeCheckResult;
|
||||||
import visitor.Visitable;
|
import visitor.Visitable;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@@ -13,6 +13,7 @@ import java.util.List;
|
|||||||
public class MemberAccessNode implements ASTNode, Visitable {
|
public class MemberAccessNode implements ASTNode, Visitable {
|
||||||
public Boolean thisExpr;
|
public Boolean thisExpr;
|
||||||
public List<String> identifiers = new ArrayList<>();
|
public List<String> identifiers = new ArrayList<>();
|
||||||
|
private ITypeNode typeNode;
|
||||||
|
|
||||||
public MemberAccessNode(Boolean thisExpr) {
|
public MemberAccessNode(Boolean thisExpr) {
|
||||||
this.thisExpr = thisExpr;
|
this.thisExpr = thisExpr;
|
||||||
@@ -31,5 +32,12 @@ public class MemberAccessNode implements ASTNode, Visitable {
|
|||||||
return visitor.analyze(this);
|
return visitor.analyze(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ITypeNode getTypeNode() {
|
||||||
|
return typeNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTypeNode(ITypeNode typeNode) {
|
||||||
|
this.typeNode = typeNode;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -1,12 +1,13 @@
|
|||||||
package ast.expressions.unaryexpressions;
|
package ast.expressions.unaryexpressions;
|
||||||
|
|
||||||
|
import ast.ASTNode;
|
||||||
import ast.expressions.IExpressionNode;
|
import ast.expressions.IExpressionNode;
|
||||||
import ast.type.type.ITypeNode;
|
|
||||||
import bytecode.visitor.MethodVisitor;
|
import bytecode.visitor.MethodVisitor;
|
||||||
import semantic.SemanticVisitor;
|
import semantic.SemanticVisitor;
|
||||||
import semantic.TypeCheckResult;
|
import typechecker.TypeCheckResult;
|
||||||
|
import visitor.Visitable;
|
||||||
|
|
||||||
public class NotNode implements IExpressionNode {
|
public class NotNode implements ASTNode, Visitable {
|
||||||
public IExpressionNode expression;
|
public IExpressionNode expression;
|
||||||
|
|
||||||
public NotNode(IExpressionNode expression) {
|
public NotNode(IExpressionNode expression) {
|
||||||
@@ -23,13 +24,4 @@ public class NotNode implements IExpressionNode {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public ITypeNode getType() {
|
|
||||||
return expression.getType();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setType(ITypeNode type) {
|
|
||||||
this.expression.setType(type);
|
|
||||||
}
|
|
||||||
}
|
}
|
@@ -6,7 +6,7 @@ import ast.type.type.*;
|
|||||||
import ast.type.ValueNode;
|
import ast.type.ValueNode;
|
||||||
import bytecode.visitor.MethodVisitor;
|
import bytecode.visitor.MethodVisitor;
|
||||||
import semantic.SemanticVisitor;
|
import semantic.SemanticVisitor;
|
||||||
import semantic.TypeCheckResult;
|
import typechecker.TypeCheckResult;
|
||||||
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
@@ -18,7 +18,7 @@ public class UnaryNode implements IExpressionNode {
|
|||||||
public NotNode notExpression;
|
public NotNode notExpression;
|
||||||
public IStatementNode statement;
|
public IStatementNode statement;
|
||||||
public IExpressionNode expression;
|
public IExpressionNode expression;
|
||||||
public ITypeNode type;
|
private ITypeNode type;
|
||||||
|
|
||||||
public UnaryNode(String value) {
|
public UnaryNode(String value) {
|
||||||
if(Objects.equals(value, "this")) {
|
if(Objects.equals(value, "this")) {
|
||||||
|
11
src/main/java/ast/literal/BooleanLiteralNode.java
Normal file
11
src/main/java/ast/literal/BooleanLiteralNode.java
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
package ast.literal;
|
||||||
|
|
||||||
|
public class BooleanLiteralNode {
|
||||||
|
private String value;
|
||||||
|
|
||||||
|
public BooleanLiteralNode(String value) {this.value = value;}
|
||||||
|
|
||||||
|
public String getValue() {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
}
|
11
src/main/java/ast/literal/CharLiteralNode.java
Normal file
11
src/main/java/ast/literal/CharLiteralNode.java
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
package ast.literal;
|
||||||
|
|
||||||
|
public class CharLiteralNode {
|
||||||
|
public String value;
|
||||||
|
|
||||||
|
public CharLiteralNode(String value) {this.value = value;}
|
||||||
|
|
||||||
|
public String getValue() {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
}
|
31
src/main/java/ast/literal/LiteralNode.java
Normal file
31
src/main/java/ast/literal/LiteralNode.java
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
package ast.literal;
|
||||||
|
|
||||||
|
import ast.expressions.IExpressionNode;
|
||||||
|
import ast.type.type.ITypeNode;
|
||||||
|
import semantic.SemanticVisitor;
|
||||||
|
import typechecker.TypeCheckResult;
|
||||||
|
|
||||||
|
public class LiteralNode implements IExpressionNode {
|
||||||
|
|
||||||
|
public String value;
|
||||||
|
private ITypeNode type;
|
||||||
|
|
||||||
|
public LiteralNode(String value, ITypeNode type) {
|
||||||
|
this.value = value;
|
||||||
|
this.type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ITypeNode getType() {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setType(ITypeNode type) {
|
||||||
|
this.type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TypeCheckResult accept(SemanticVisitor visitor) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
@@ -32,7 +32,8 @@ public class ConstructorNode extends MethodNode implements Visitable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public boolean isSame(MethodNode methodNode) {
|
public boolean isSame(MethodNode methodNode) {
|
||||||
if (!(Objects.equals(this.identifier, methodNode.getIdentifier())) || getParameters().size() != methodNode.getParameters().size()) {
|
if (!(Objects.equals(this.identifier, methodNode.getIdentifier()))
|
||||||
|
|| getParameters().size() != methodNode.getParameters().size()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -3,8 +3,9 @@ package ast.members;
|
|||||||
import ast.type.AccessModifierNode;
|
import ast.type.AccessModifierNode;
|
||||||
import ast.type.type.ITypeNode;
|
import ast.type.type.ITypeNode;
|
||||||
import bytecode.visitor.ClassVisitor;
|
import bytecode.visitor.ClassVisitor;
|
||||||
|
import bytecode.visitor.MethodVisitor;
|
||||||
import semantic.SemanticVisitor;
|
import semantic.SemanticVisitor;
|
||||||
import semantic.TypeCheckResult;
|
import typechecker.TypeCheckResult;
|
||||||
import visitor.Visitable;
|
import visitor.Visitable;
|
||||||
|
|
||||||
public class FieldNode implements MemberNode, Visitable {
|
public class FieldNode implements MemberNode, Visitable {
|
||||||
|
@@ -5,6 +5,7 @@ import bytecode.visitor.MethodVisitor;
|
|||||||
import visitor.Visitable;
|
import visitor.Visitable;
|
||||||
|
|
||||||
public class MainMethodNode extends MethodNode implements Visitable {
|
public class MainMethodNode extends MethodNode implements Visitable {
|
||||||
|
public BlockNode block;
|
||||||
|
|
||||||
public MainMethodNode(BlockNode block) {
|
public MainMethodNode(BlockNode block) {
|
||||||
this.block = block;
|
this.block = block;
|
||||||
|
@@ -13,5 +13,4 @@ import ast.ASTNode;
|
|||||||
@JsonSubTypes.Type(value = FieldNode.class, name = "Field") }
|
@JsonSubTypes.Type(value = FieldNode.class, name = "Field") }
|
||||||
)
|
)
|
||||||
|
|
||||||
public interface MemberNode extends ASTNode {
|
public interface MemberNode extends ASTNode {}
|
||||||
}
|
|
||||||
|
@@ -6,7 +6,7 @@ import ast.type.AccessModifierNode;
|
|||||||
import ast.type.type.*;
|
import ast.type.type.*;
|
||||||
import bytecode.visitor.MethodVisitor;
|
import bytecode.visitor.MethodVisitor;
|
||||||
import semantic.SemanticVisitor;
|
import semantic.SemanticVisitor;
|
||||||
import semantic.TypeCheckResult;
|
import typechecker.TypeCheckResult;
|
||||||
import visitor.Visitable;
|
import visitor.Visitable;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@@ -15,9 +15,9 @@ import java.util.Objects;
|
|||||||
|
|
||||||
public class MethodNode implements MemberNode, Visitable {
|
public class MethodNode implements MemberNode, Visitable {
|
||||||
public AccessModifierNode accesModifier;
|
public AccessModifierNode accesModifier;
|
||||||
public ITypeNode type;
|
private ITypeNode type;
|
||||||
public Boolean voidType;
|
public Boolean voidType;
|
||||||
public String identifier;
|
private String identifier;
|
||||||
public List<ParameterNode> parameters = new ArrayList<>();
|
public List<ParameterNode> parameters = new ArrayList<>();
|
||||||
public BlockNode block;
|
public BlockNode block;
|
||||||
|
|
||||||
|
@@ -3,7 +3,7 @@ package ast.parameters;
|
|||||||
import ast.ASTNode;
|
import ast.ASTNode;
|
||||||
import ast.type.type.*;
|
import ast.type.type.*;
|
||||||
import semantic.SemanticVisitor;
|
import semantic.SemanticVisitor;
|
||||||
import semantic.TypeCheckResult;
|
import typechecker.TypeCheckResult;
|
||||||
import visitor.Visitable;
|
import visitor.Visitable;
|
||||||
|
|
||||||
public class ParameterNode implements ASTNode, Visitable {
|
public class ParameterNode implements ASTNode, Visitable {
|
||||||
|
11
src/main/java/ast/statement/BlockStatementNode.java
Normal file
11
src/main/java/ast/statement/BlockStatementNode.java
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
package ast.statement;
|
||||||
|
|
||||||
|
import ast.statements.IStatementNode;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class BlockStatementNode {
|
||||||
|
List<IStatementNode> statements;
|
||||||
|
|
||||||
|
public BlockStatementNode(List<IStatementNode> statements) {this.statements = statements;}
|
||||||
|
}
|
@@ -3,7 +3,7 @@ package ast.statementexpressions;
|
|||||||
import ast.expressions.IExpressionNode;
|
import ast.expressions.IExpressionNode;
|
||||||
import bytecode.visitor.MethodVisitor;
|
import bytecode.visitor.MethodVisitor;
|
||||||
import semantic.SemanticVisitor;
|
import semantic.SemanticVisitor;
|
||||||
import semantic.TypeCheckResult;
|
import typechecker.TypeCheckResult;
|
||||||
|
|
||||||
public class AssignNode implements IStatementExpressionNode {
|
public class AssignNode implements IStatementExpressionNode {
|
||||||
public AssignableNode assignable;
|
public AssignableNode assignable;
|
||||||
|
@@ -3,11 +3,11 @@ package ast.statementexpressions;
|
|||||||
import ast.expressions.unaryexpressions.MemberAccessNode;
|
import ast.expressions.unaryexpressions.MemberAccessNode;
|
||||||
import ast.type.type.ITypeNode;
|
import ast.type.type.ITypeNode;
|
||||||
import semantic.SemanticVisitor;
|
import semantic.SemanticVisitor;
|
||||||
import semantic.TypeCheckResult;
|
import typechecker.TypeCheckResult;
|
||||||
|
|
||||||
public class AssignableNode implements IStatementExpressionNode {
|
public class AssignableNode implements IStatementExpressionNode {
|
||||||
public String identifier;
|
public String identifier;
|
||||||
public ITypeNode typeNode;
|
private ITypeNode typeNode;
|
||||||
|
|
||||||
public MemberAccessNode memberAccess;
|
public MemberAccessNode memberAccess;
|
||||||
|
|
||||||
@@ -24,6 +24,10 @@ public class AssignableNode implements IStatementExpressionNode {
|
|||||||
return visitor.analyze(this);
|
return visitor.analyze(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ITypeNode getTypeNode() {
|
||||||
|
return typeNode;
|
||||||
|
}
|
||||||
|
|
||||||
public void setTypeNode(ITypeNode typeNode) {
|
public void setTypeNode(ITypeNode typeNode) {
|
||||||
this.typeNode = typeNode;
|
this.typeNode = typeNode;
|
||||||
}
|
}
|
||||||
|
@@ -2,5 +2,4 @@ package ast.statementexpressions;
|
|||||||
|
|
||||||
import ast.statements.IStatementNode;
|
import ast.statements.IStatementNode;
|
||||||
|
|
||||||
public interface IStatementExpressionNode extends IStatementNode {
|
public interface IStatementExpressionNode extends IStatementNode {}
|
||||||
}
|
|
||||||
|
@@ -3,7 +3,7 @@ package ast.statementexpressions;
|
|||||||
import ast.expressions.IExpressionNode;
|
import ast.expressions.IExpressionNode;
|
||||||
import bytecode.visitor.MethodVisitor;
|
import bytecode.visitor.MethodVisitor;
|
||||||
import semantic.SemanticVisitor;
|
import semantic.SemanticVisitor;
|
||||||
import semantic.TypeCheckResult;
|
import typechecker.TypeCheckResult;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@@ -2,8 +2,10 @@ package ast.statementexpressions.crementexpressions;
|
|||||||
|
|
||||||
import ast.statementexpressions.AssignableNode;
|
import ast.statementexpressions.AssignableNode;
|
||||||
import ast.statementexpressions.IStatementExpressionNode;
|
import ast.statementexpressions.IStatementExpressionNode;
|
||||||
|
import bytecode.visitor.MethodVisitor;
|
||||||
import semantic.SemanticVisitor;
|
import semantic.SemanticVisitor;
|
||||||
import semantic.TypeCheckResult;
|
import typechecker.TypeCheckResult;
|
||||||
|
import visitor.Visitable;
|
||||||
|
|
||||||
public class DecrementNode implements IStatementExpressionNode {
|
public class DecrementNode implements IStatementExpressionNode {
|
||||||
public CrementType crementType;
|
public CrementType crementType;
|
||||||
|
@@ -2,8 +2,9 @@ package ast.statementexpressions.crementexpressions;
|
|||||||
|
|
||||||
import ast.statementexpressions.AssignableNode;
|
import ast.statementexpressions.AssignableNode;
|
||||||
import ast.statementexpressions.IStatementExpressionNode;
|
import ast.statementexpressions.IStatementExpressionNode;
|
||||||
|
import bytecode.visitor.MethodVisitor;
|
||||||
import semantic.SemanticVisitor;
|
import semantic.SemanticVisitor;
|
||||||
import semantic.TypeCheckResult;
|
import typechecker.TypeCheckResult;
|
||||||
|
|
||||||
public class IncrementNode implements IStatementExpressionNode {
|
public class IncrementNode implements IStatementExpressionNode {
|
||||||
public CrementType crementType;
|
public CrementType crementType;
|
||||||
|
@@ -4,7 +4,7 @@ import ast.ASTNode;
|
|||||||
import ast.expressions.IExpressionNode;
|
import ast.expressions.IExpressionNode;
|
||||||
import bytecode.visitor.MethodVisitor;
|
import bytecode.visitor.MethodVisitor;
|
||||||
import semantic.SemanticVisitor;
|
import semantic.SemanticVisitor;
|
||||||
import semantic.TypeCheckResult;
|
import typechecker.TypeCheckResult;
|
||||||
import visitor.Visitable;
|
import visitor.Visitable;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
@@ -2,17 +2,15 @@ package ast.statementexpressions.methodcallstatementnexpressions;
|
|||||||
|
|
||||||
import ast.expressions.IExpressionNode;
|
import ast.expressions.IExpressionNode;
|
||||||
import ast.statements.IStatementNode;
|
import ast.statements.IStatementNode;
|
||||||
import ast.type.type.ITypeNode;
|
|
||||||
import bytecode.visitor.MethodVisitor;
|
import bytecode.visitor.MethodVisitor;
|
||||||
import semantic.SemanticVisitor;
|
import semantic.SemanticVisitor;
|
||||||
import semantic.TypeCheckResult;
|
import typechecker.TypeCheckResult;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class MethodCallNode implements IStatementNode {
|
public class MethodCallNode implements IStatementNode {
|
||||||
public TargetNode target;
|
public TargetNode target;
|
||||||
public ITypeNode type;
|
|
||||||
public List<ChainedMethodNode> chainedMethods = new ArrayList<>();
|
public List<ChainedMethodNode> chainedMethods = new ArrayList<>();
|
||||||
public String identifier;
|
public String identifier;
|
||||||
public List<IExpressionNode> parameters = new ArrayList<>();
|
public List<IExpressionNode> parameters = new ArrayList<>();
|
||||||
|
@@ -3,8 +3,9 @@ package ast.statementexpressions.methodcallstatementnexpressions;
|
|||||||
import ast.ASTNode;
|
import ast.ASTNode;
|
||||||
import ast.expressions.unaryexpressions.MemberAccessNode;
|
import ast.expressions.unaryexpressions.MemberAccessNode;
|
||||||
import ast.statementexpressions.NewDeclarationNode;
|
import ast.statementexpressions.NewDeclarationNode;
|
||||||
|
import bytecode.visitor.MethodVisitor;
|
||||||
import semantic.SemanticVisitor;
|
import semantic.SemanticVisitor;
|
||||||
import semantic.TypeCheckResult;
|
import typechecker.TypeCheckResult;
|
||||||
import visitor.Visitable;
|
import visitor.Visitable;
|
||||||
|
|
||||||
public class TargetNode implements ASTNode, Visitable {
|
public class TargetNode implements ASTNode, Visitable {
|
||||||
|
@@ -1,7 +1,8 @@
|
|||||||
package ast.statements;
|
package ast.statements;
|
||||||
|
|
||||||
|
import ast.ASTNode;
|
||||||
import semantic.SemanticVisitor;
|
import semantic.SemanticVisitor;
|
||||||
import semantic.TypeCheckResult;
|
import typechecker.TypeCheckResult;
|
||||||
import visitor.Visitable;
|
import visitor.Visitable;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@@ -10,8 +11,7 @@ import java.util.List;
|
|||||||
public class BlockNode implements IStatementNode, Visitable {
|
public class BlockNode implements IStatementNode, Visitable {
|
||||||
public List<IStatementNode> statements = new ArrayList<>();
|
public List<IStatementNode> statements = new ArrayList<>();
|
||||||
|
|
||||||
public BlockNode() {
|
public BlockNode() {}
|
||||||
}
|
|
||||||
|
|
||||||
public void addStatement(IStatementNode statement) {
|
public void addStatement(IStatementNode statement) {
|
||||||
statements.add(statement);
|
statements.add(statement);
|
||||||
|
10
src/main/java/ast/statements/BlockStatementNode.java
Normal file
10
src/main/java/ast/statements/BlockStatementNode.java
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
package ast.statements;
|
||||||
|
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class BlockStatementNode {
|
||||||
|
List<IStatementNode> statements;
|
||||||
|
|
||||||
|
public BlockStatementNode(List<IStatementNode> statements) {this.statements = statements;}
|
||||||
|
}
|
@@ -1,7 +1,7 @@
|
|||||||
package ast.statements;
|
package ast.statements;
|
||||||
|
|
||||||
import semantic.SemanticVisitor;
|
import semantic.SemanticVisitor;
|
||||||
import semantic.TypeCheckResult;
|
import typechecker.TypeCheckResult;
|
||||||
|
|
||||||
public class ElseNode implements IStatementNode {
|
public class ElseNode implements IStatementNode {
|
||||||
public BlockNode block;
|
public BlockNode block;
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
package ast.statements;
|
package ast.statements;
|
||||||
|
|
||||||
import semantic.SemanticVisitor;
|
import semantic.SemanticVisitor;
|
||||||
import semantic.TypeCheckResult;
|
import typechecker.TypeCheckResult;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@@ -2,7 +2,7 @@ package ast.statements;
|
|||||||
|
|
||||||
import ast.expressions.IExpressionNode;
|
import ast.expressions.IExpressionNode;
|
||||||
import semantic.SemanticVisitor;
|
import semantic.SemanticVisitor;
|
||||||
import semantic.TypeCheckResult;
|
import typechecker.TypeCheckResult;
|
||||||
|
|
||||||
public class IfNode implements IStatementNode {
|
public class IfNode implements IStatementNode {
|
||||||
public IExpressionNode expression;
|
public IExpressionNode expression;
|
||||||
|
@@ -4,7 +4,7 @@ import ast.expressions.IExpressionNode;
|
|||||||
import ast.type.type.*;
|
import ast.type.type.*;
|
||||||
import bytecode.visitor.MethodVisitor;
|
import bytecode.visitor.MethodVisitor;
|
||||||
import semantic.SemanticVisitor;
|
import semantic.SemanticVisitor;
|
||||||
import semantic.TypeCheckResult;
|
import typechecker.TypeCheckResult;
|
||||||
|
|
||||||
public class LocalVariableDeclarationNode implements IStatementNode {
|
public class LocalVariableDeclarationNode implements IStatementNode {
|
||||||
public ITypeNode type;
|
public ITypeNode type;
|
||||||
|
@@ -3,7 +3,7 @@ package ast.statements;
|
|||||||
import ast.expressions.IExpressionNode;
|
import ast.expressions.IExpressionNode;
|
||||||
import bytecode.visitor.MethodVisitor;
|
import bytecode.visitor.MethodVisitor;
|
||||||
import semantic.SemanticVisitor;
|
import semantic.SemanticVisitor;
|
||||||
import semantic.TypeCheckResult;
|
import typechecker.TypeCheckResult;
|
||||||
|
|
||||||
public class ReturnNode implements IStatementNode {
|
public class ReturnNode implements IStatementNode {
|
||||||
public IExpressionNode expression;
|
public IExpressionNode expression;
|
||||||
|
@@ -2,7 +2,7 @@ package ast.statements;
|
|||||||
|
|
||||||
import ast.expressions.IExpressionNode;
|
import ast.expressions.IExpressionNode;
|
||||||
import semantic.SemanticVisitor;
|
import semantic.SemanticVisitor;
|
||||||
import semantic.TypeCheckResult;
|
import typechecker.TypeCheckResult;
|
||||||
|
|
||||||
public class WhileNode implements IStatementNode {
|
public class WhileNode implements IStatementNode {
|
||||||
public IExpressionNode expression;
|
public IExpressionNode expression;
|
||||||
@@ -13,10 +13,6 @@ public class WhileNode implements IStatementNode {
|
|||||||
this.block = block;
|
this.block = block;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void test() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TypeCheckResult accept(SemanticVisitor visitor) {
|
public TypeCheckResult accept(SemanticVisitor visitor) {
|
||||||
return visitor.analyze(this);
|
return visitor.analyze(this);
|
||||||
|
@@ -3,7 +3,7 @@ package ast.type;
|
|||||||
import ast.ASTNode;
|
import ast.ASTNode;
|
||||||
import bytecode.visitor.MethodVisitor;
|
import bytecode.visitor.MethodVisitor;
|
||||||
import semantic.SemanticVisitor;
|
import semantic.SemanticVisitor;
|
||||||
import semantic.TypeCheckResult;
|
import typechecker.TypeCheckResult;
|
||||||
import visitor.Visitable;
|
import visitor.Visitable;
|
||||||
|
|
||||||
public class ValueNode implements ASTNode, Visitable {
|
public class ValueNode implements ASTNode, Visitable {
|
||||||
|
@@ -2,7 +2,7 @@ package ast.type.type;
|
|||||||
|
|
||||||
public class BaseType implements ITypeNode {
|
public class BaseType implements ITypeNode {
|
||||||
|
|
||||||
public final TypeEnum typeEnum;
|
private TypeEnum typeEnum;
|
||||||
|
|
||||||
public BaseType(TypeEnum typeEnum) {
|
public BaseType(TypeEnum typeEnum) {
|
||||||
this.typeEnum = typeEnum;
|
this.typeEnum = typeEnum;
|
||||||
@@ -21,6 +21,8 @@ public class BaseType implements ITypeNode {
|
|||||||
if (getClass() != obj.getClass())
|
if (getClass() != obj.getClass())
|
||||||
return false;
|
return false;
|
||||||
BaseType other = (BaseType) obj;
|
BaseType other = (BaseType) obj;
|
||||||
return typeEnum == other.typeEnum;
|
if (typeEnum != other.typeEnum)
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,4 +1,5 @@
|
|||||||
package ast.type.type;
|
package ast.type.type;
|
||||||
|
|
||||||
public interface ITypeNode {
|
public interface ITypeNode {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -2,7 +2,7 @@ package ast.type.type;
|
|||||||
|
|
||||||
public class ReferenceType implements ITypeNode{
|
public class ReferenceType implements ITypeNode{
|
||||||
|
|
||||||
public final String identifier;
|
private String identifier;
|
||||||
|
|
||||||
public ReferenceType(String identifier) {
|
public ReferenceType(String identifier) {
|
||||||
this.identifier = identifier;
|
this.identifier = identifier;
|
||||||
@@ -22,8 +22,11 @@ public class ReferenceType implements ITypeNode {
|
|||||||
return false;
|
return false;
|
||||||
ReferenceType other = (ReferenceType) obj;
|
ReferenceType other = (ReferenceType) obj;
|
||||||
if (identifier == null) {
|
if (identifier == null) {
|
||||||
return other.identifier == null;
|
if (other.identifier != null)
|
||||||
} else return identifier.equals(other.identifier);
|
return false;
|
||||||
|
} else if (!identifier.equals(other.identifier))
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -4,5 +4,6 @@ public enum TypeEnum {
|
|||||||
VOID,
|
VOID,
|
||||||
INT,
|
INT,
|
||||||
CHAR,
|
CHAR,
|
||||||
BOOL
|
BOOL;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -17,9 +17,9 @@ public class ByteCodeGenerator implements ProgramVisitor {
|
|||||||
|
|
||||||
private JarOutputStream jarOutputStream;
|
private JarOutputStream jarOutputStream;
|
||||||
private ByteArrayOutputStream byteArrayOutputStream;
|
private ByteArrayOutputStream byteArrayOutputStream;
|
||||||
private final String outputDirectory;
|
private String outputDirectory;
|
||||||
private final boolean generateJar;
|
private boolean generateJar;
|
||||||
private final boolean generateClassFiles;
|
private boolean generateClassFiles;
|
||||||
|
|
||||||
public ByteCodeGenerator(String outputDirectory, boolean generateJar, boolean generateClassFiles) {
|
public ByteCodeGenerator(String outputDirectory, boolean generateJar, boolean generateClassFiles) {
|
||||||
this.outputDirectory = outputDirectory;
|
this.outputDirectory = outputDirectory;
|
||||||
|
@@ -19,12 +19,12 @@ import java.util.jar.JarOutputStream;
|
|||||||
|
|
||||||
|
|
||||||
public class ClassCodeGen implements ClassVisitor {
|
public class ClassCodeGen implements ClassVisitor {
|
||||||
private final Mapper mapper;
|
private Mapper mapper;
|
||||||
private ClassWriter classWriter;
|
private ClassWriter classWriter;
|
||||||
private final JarOutputStream jarOutputStream;
|
private JarOutputStream jarOutputStream;
|
||||||
private final String outputDirectory;
|
private String outputDirectory;
|
||||||
private final boolean generateJar;
|
private boolean generateJar;
|
||||||
private final boolean generateClassFiles;
|
private boolean generateClassFiles;
|
||||||
|
|
||||||
public ClassCodeGen(JarOutputStream jarOutputStream, String outputDirectory, boolean generateJar, boolean generateClassFiles) {
|
public ClassCodeGen(JarOutputStream jarOutputStream, String outputDirectory, boolean generateJar, boolean generateClassFiles) {
|
||||||
mapper = new Mapper();
|
mapper = new Mapper();
|
||||||
|
@@ -16,6 +16,7 @@ import ast.statementexpressions.crementexpressions.DecrementNode;
|
|||||||
import ast.statementexpressions.crementexpressions.IncrementNode;
|
import ast.statementexpressions.crementexpressions.IncrementNode;
|
||||||
import ast.statementexpressions.methodcallstatementnexpressions.ChainedMethodNode;
|
import ast.statementexpressions.methodcallstatementnexpressions.ChainedMethodNode;
|
||||||
import ast.statementexpressions.methodcallstatementnexpressions.MethodCallNode;
|
import ast.statementexpressions.methodcallstatementnexpressions.MethodCallNode;
|
||||||
|
import ast.statementexpressions.methodcallstatementnexpressions.TargetNode;
|
||||||
import ast.statements.*;
|
import ast.statements.*;
|
||||||
import ast.type.ValueNode;
|
import ast.type.ValueNode;
|
||||||
import ast.type.type.BaseType;
|
import ast.type.type.BaseType;
|
||||||
@@ -34,11 +35,11 @@ import static org.objectweb.asm.Opcodes.*;
|
|||||||
|
|
||||||
public class MethodCodeGen implements bytecode.visitor.MethodVisitor {
|
public class MethodCodeGen implements bytecode.visitor.MethodVisitor {
|
||||||
|
|
||||||
private final ClassWriter classWriter;
|
private ClassWriter classWriter;
|
||||||
private final Mapper mapper;
|
private Mapper mapper;
|
||||||
private MethodVisitor methodVisitor;
|
private MethodVisitor methodVisitor;
|
||||||
|
|
||||||
private final List<String> localVariables;
|
private List<String> localVariables;
|
||||||
|
|
||||||
public MethodCodeGen(ClassWriter classWriter) {
|
public MethodCodeGen(ClassWriter classWriter) {
|
||||||
this.classWriter = classWriter;
|
this.classWriter = classWriter;
|
||||||
@@ -157,8 +158,8 @@ public class MethodCodeGen implements bytecode.visitor.MethodVisitor {
|
|||||||
if (dotNode.dotExpression != null) {
|
if (dotNode.dotExpression != null) {
|
||||||
dotNode.dotExpression.accept(this);
|
dotNode.dotExpression.accept(this);
|
||||||
}
|
}
|
||||||
if (dotNode.dotSubtractionExpression != null) {
|
if (dotNode.dotSubstractionExpression != null) {
|
||||||
dotNode.dotSubtractionExpression.accept(this);
|
dotNode.dotSubstractionExpression.accept(this);
|
||||||
}
|
}
|
||||||
if (dotNode.operator != null) {
|
if (dotNode.operator != null) {
|
||||||
switch (dotNode.operator) {
|
switch (dotNode.operator) {
|
||||||
@@ -176,17 +177,17 @@ public class MethodCodeGen implements bytecode.visitor.MethodVisitor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(DotSubtractionNode dotSubtractionNode) {
|
public void visit(DotSubstractionNode dotSubstractionNode) {
|
||||||
if (dotSubtractionNode.value != null) {
|
if (dotSubstractionNode.value != null) {
|
||||||
dotSubtractionNode.value.accept(this);
|
dotSubstractionNode.value.accept(this);
|
||||||
} else if (dotSubtractionNode.identifier != null) {
|
} else if (dotSubstractionNode.identifier != null) {
|
||||||
methodVisitor.visitVarInsn(ILOAD, localVariables.indexOf(dotSubtractionNode.identifier));
|
methodVisitor.visitVarInsn(ILOAD, localVariables.indexOf(dotSubstractionNode.identifier));
|
||||||
} else if (dotSubtractionNode.memberAccess != null) {
|
} else if (dotSubstractionNode.memberAccess != null) {
|
||||||
dotSubtractionNode.memberAccess.accept(this);
|
dotSubstractionNode.memberAccess.accept(this);
|
||||||
} else if (dotSubtractionNode.methodCall != null) {
|
} else if (dotSubstractionNode.methodCall != null) {
|
||||||
dotSubtractionNode.methodCall.accept(this);
|
dotSubstractionNode.methodCall.accept(this);
|
||||||
} else if (dotSubtractionNode.calculationExpression != null) {
|
} else if (dotSubstractionNode.calculationExpression != null) {
|
||||||
dotSubtractionNode.calculationExpression.accept(this);
|
dotSubstractionNode.calculationExpression.accept(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -386,7 +387,8 @@ public class MethodCodeGen implements bytecode.visitor.MethodVisitor {
|
|||||||
@Override
|
@Override
|
||||||
public void visit(AssignNode assignNode) {
|
public void visit(AssignNode assignNode) {
|
||||||
// Process expression
|
// Process expression
|
||||||
if (assignNode.expression instanceof IncrementNode incrementNode) {
|
if (assignNode.expression instanceof IncrementNode) {
|
||||||
|
IncrementNode incrementNode = (IncrementNode) assignNode.expression;
|
||||||
if (incrementNode.crementType.equals(CrementType.PREFIX)) { // ++i
|
if (incrementNode.crementType.equals(CrementType.PREFIX)) { // ++i
|
||||||
methodVisitor.visitIincInsn(localVariables.indexOf(incrementNode.assignableExpression.identifier), 1);
|
methodVisitor.visitIincInsn(localVariables.indexOf(incrementNode.assignableExpression.identifier), 1);
|
||||||
assign(assignNode);
|
assign(assignNode);
|
||||||
@@ -394,7 +396,8 @@ public class MethodCodeGen implements bytecode.visitor.MethodVisitor {
|
|||||||
assign(assignNode);
|
assign(assignNode);
|
||||||
methodVisitor.visitIincInsn(localVariables.indexOf(incrementNode.assignableExpression.identifier), 1);
|
methodVisitor.visitIincInsn(localVariables.indexOf(incrementNode.assignableExpression.identifier), 1);
|
||||||
}
|
}
|
||||||
} else if (assignNode.expression instanceof DecrementNode decrementNode) {
|
} else if (assignNode.expression instanceof DecrementNode) {
|
||||||
|
DecrementNode decrementNode = (DecrementNode) assignNode.expression;
|
||||||
if (decrementNode.crementType.equals(CrementType.PREFIX)) {
|
if (decrementNode.crementType.equals(CrementType.PREFIX)) {
|
||||||
methodVisitor.visitIincInsn(localVariables.indexOf(decrementNode.assignableExpression.identifier), -1);
|
methodVisitor.visitIincInsn(localVariables.indexOf(decrementNode.assignableExpression.identifier), -1);
|
||||||
assign(assignNode);
|
assign(assignNode);
|
||||||
|
@@ -8,54 +8,46 @@ import ast.members.ConstructorNode;
|
|||||||
import ast.members.MainMethodNode;
|
import ast.members.MainMethodNode;
|
||||||
import ast.members.MethodNode;
|
import ast.members.MethodNode;
|
||||||
import ast.statementexpressions.AssignNode;
|
import ast.statementexpressions.AssignNode;
|
||||||
|
import ast.statementexpressions.AssignableNode;
|
||||||
import ast.statementexpressions.NewDeclarationNode;
|
import ast.statementexpressions.NewDeclarationNode;
|
||||||
|
import ast.statementexpressions.crementexpressions.DecrementNode;
|
||||||
|
import ast.statementexpressions.crementexpressions.IncrementNode;
|
||||||
import ast.statementexpressions.methodcallstatementnexpressions.ChainedMethodNode;
|
import ast.statementexpressions.methodcallstatementnexpressions.ChainedMethodNode;
|
||||||
import ast.statementexpressions.methodcallstatementnexpressions.MethodCallNode;
|
import ast.statementexpressions.methodcallstatementnexpressions.MethodCallNode;
|
||||||
|
import ast.statementexpressions.methodcallstatementnexpressions.TargetNode;
|
||||||
import ast.statements.*;
|
import ast.statements.*;
|
||||||
import ast.type.ValueNode;
|
import ast.type.ValueNode;
|
||||||
|
|
||||||
public interface MethodVisitor {
|
public interface MethodVisitor {
|
||||||
// members
|
// members
|
||||||
void visit(ConstructorNode constructorNode);
|
void visit(ConstructorNode constructorNode);
|
||||||
|
|
||||||
void visit(MethodNode methodNode);
|
void visit(MethodNode methodNode);
|
||||||
|
|
||||||
void visit(MainMethodNode mainMethodNode);
|
void visit(MainMethodNode mainMethodNode);
|
||||||
|
|
||||||
// Binary expressions
|
// Binary expressions
|
||||||
void visit(BinaryNode binaryNode);
|
void visit(BinaryNode binaryNode);
|
||||||
|
|
||||||
void visit(CalculationNode calculationNode);
|
void visit(CalculationNode calculationNode);
|
||||||
|
|
||||||
void visit(DotNode dotNode);
|
void visit(DotNode dotNode);
|
||||||
|
void visit(DotSubstractionNode dotSubstractionNode);
|
||||||
void visit(DotSubtractionNode dotSubtractionNode);
|
|
||||||
|
|
||||||
void visit(NonCalculationNode nonCalculationNode);
|
void visit(NonCalculationNode nonCalculationNode);
|
||||||
|
|
||||||
// Unary expressions
|
// Unary expressions
|
||||||
void visit(MemberAccessNode memberAccessNode);
|
void visit(MemberAccessNode memberAccessNode);
|
||||||
|
|
||||||
void visit(NotNode notExpressionNode);
|
void visit(NotNode notExpressionNode);
|
||||||
|
|
||||||
void visit(UnaryNode unaryExpressionNode);
|
void visit(UnaryNode unaryExpressionNode);
|
||||||
|
|
||||||
// statements
|
// statements
|
||||||
void visit(IfElseNode ifElseNode);
|
void visit(IfElseNode ifElseNode);
|
||||||
|
|
||||||
void visit(LocalVariableDeclarationNode localVariableDeclarationNode);
|
void visit(LocalVariableDeclarationNode localVariableDeclarationNode);
|
||||||
|
|
||||||
void visit(ReturnNode returnNode);
|
void visit(ReturnNode returnNode);
|
||||||
|
|
||||||
void visit(WhileNode whileNode);
|
void visit(WhileNode whileNode);
|
||||||
|
|
||||||
// statement expression
|
// statement expression
|
||||||
void visit(ChainedMethodNode chainedMethodNode);
|
void visit(ChainedMethodNode chainedMethodNode);
|
||||||
|
|
||||||
void visit(MethodCallNode methodCallNode);
|
void visit(MethodCallNode methodCallNode);
|
||||||
|
|
||||||
void visit(AssignNode assignNode);
|
void visit(AssignNode assignNode);
|
||||||
|
|
||||||
void visit(NewDeclarationNode newDeclarationNode);
|
void visit(NewDeclarationNode newDeclarationNode);
|
||||||
|
|
||||||
// type
|
// type
|
||||||
|
@@ -13,17 +13,16 @@ import org.antlr.v4.runtime.tree.ParseTree;
|
|||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Start miniCompiler using make:
|
* Start Raupenpiler using make:
|
||||||
* <p> <code> cd .\src\test\ </code>
|
* <p> <code> cd .\src\test\ </code>
|
||||||
* <p> <code> make clean compile-miniCompiler </code>
|
* <p> <code> make clean compile-raupenpiler </code>
|
||||||
* <p> Start miniCompiler using jar:
|
* <p> Start Raupenpiler using jar:
|
||||||
* <p> <code> java.exe -DgenJar=true_OR_false -DgenClass=true_OR_false -jar path_to_jar\JavaCompiler-1.0-jar-with-dependencies.jar 'path_to_input_file.java' 'path_to_output_directory' </code>
|
* <p> <code> java.exe -jar path_to_jar\JavaCompiler-1.0-jar-with-dependencies.jar 'path_to_input_file.java' 'path_to_output_directory' </code>
|
||||||
* <p> Example (jar needs to be in the target directory, compile with make or mvn package first):
|
* <p> Example (jar needs to be in the target directory, compile with make or mvn package first):
|
||||||
* <code> java.exe -DgenJar=true -DgenClass=true -jar .\target\JavaCompiler-1.0-jar-with-dependencies.jar 'src/main/resources/input/CompilerInput.java' 'src/main/resources/output' </code>
|
* <code> java.exe -jar .\target\JavaCompiler-1.0-jar-with-dependencies.jar 'src/main/resources/input/CompilerInput.java' 'src/main/resources/output' </code>
|
||||||
*/
|
*/
|
||||||
public class Main {
|
public class Main {
|
||||||
public static void main(String[] args) throws Exception {
|
public static void main(String[] args) throws Exception {
|
||||||
@@ -40,6 +39,16 @@ public class Main {
|
|||||||
System.err.println("Error reading the file: " + e.getMessage());
|
System.err.println("Error reading the file: " + e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/* !!! Else Branch (main ohne args starten) ist nicht zur Verwendung vorgesehen, immer mit args starten !!!
|
||||||
|
else {
|
||||||
|
try {
|
||||||
|
CharStream codeCharStream = CharStreams.fromPath(Paths.get("src/main/resources/input/CompilerInput.java"));
|
||||||
|
compileFile(codeCharStream);
|
||||||
|
} catch (IOException e) {
|
||||||
|
System.err.println("Error reading the file: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -56,7 +65,7 @@ public class Main {
|
|||||||
*/
|
*/
|
||||||
static void compileFile(CharStream inputCharStream, String outputDirectoryPath) {
|
static void compileFile(CharStream inputCharStream, String outputDirectoryPath) {
|
||||||
// Initialize the logger
|
// Initialize the logger
|
||||||
new MiniCompilerLogger();
|
new RaupenLogger();
|
||||||
|
|
||||||
/* ------------------------- Scanner -> tokens ------------------------- */
|
/* ------------------------- Scanner -> tokens ------------------------- */
|
||||||
// Use the SimpleJavaLexer to tokenize the input CharStream
|
// Use the SimpleJavaLexer to tokenize the input CharStream
|
||||||
@@ -64,46 +73,34 @@ public class Main {
|
|||||||
CommonTokenStream tokenStream = new CommonTokenStream(lexer);
|
CommonTokenStream tokenStream = new CommonTokenStream(lexer);
|
||||||
tokenStream.fill();
|
tokenStream.fill();
|
||||||
// Log the tokens
|
// Log the tokens
|
||||||
MiniCompilerLogger.logScanner(tokenStream);
|
RaupenLogger.logScanner(tokenStream);
|
||||||
|
|
||||||
/*------------------------- Parser -> Parsetree -------------------------*/
|
/*------------------------- Parser -> Parsetree -------------------------*/
|
||||||
// Use the SimpleJavaParser to parse the tokens and generate a ParseTree
|
// Use the SimpleJavaParser to parse the tokens and generate a ParseTree
|
||||||
SimpleJavaParser parser = new SimpleJavaParser(tokenStream);
|
SimpleJavaParser parser = new SimpleJavaParser(tokenStream);
|
||||||
ParseTree parseTree = parser.program(); // parse the input
|
ParseTree parseTree = parser.program(); // parse the input
|
||||||
// Log the ParseTree
|
// Log the ParseTree
|
||||||
MiniCompilerLogger.logParser(parseTree, parser);
|
RaupenLogger.logParser(parseTree, parser);
|
||||||
|
|
||||||
/*------------------------- AST builder -> AST -------------------------*/
|
/*------------------------- AST builder -> AST -------------------------*/
|
||||||
// Use the ASTBuilder to visit the ParseTree and generate an Abstract Syntax Tree (AST)
|
// Use the ASTBuilder to visit the ParseTree and generate an Abstract Syntax Tree (AST)
|
||||||
ASTBuilder astBuilder = new ASTBuilder();
|
ASTBuilder astBuilder = new ASTBuilder();
|
||||||
ASTNode abstractSyntaxTree = astBuilder.visit(parseTree);
|
ASTNode abstractSyntaxTree = astBuilder.visit(parseTree);
|
||||||
// Log the AST
|
// Log the AST
|
||||||
MiniCompilerLogger.logAST(abstractSyntaxTree);
|
RaupenLogger.logAST(abstractSyntaxTree);
|
||||||
|
|
||||||
/*------------------------- Semantic Analyzer -> typed AST -------------------------*/
|
/*------------------------- Semantic Analyzer -> typed AST -------------------------*/
|
||||||
// Use the SemanticAnalyzer to generate a typed AST
|
// Use the SemanticAnalyzer to generate a typed AST
|
||||||
ASTNode typedAst = SemanticAnalyzer.generateTast(abstractSyntaxTree);
|
//ASTNode typedAst = SemanticAnalyzer.generateTast(abstractSyntaxTree);
|
||||||
// Log the typed AST
|
// Log the typed AST
|
||||||
MiniCompilerLogger.logSemanticAnalyzer(typedAst);
|
RaupenLogger.logSemanticAnalyzer(abstractSyntaxTree);
|
||||||
|
|
||||||
if(SemanticAnalyzer.errors.isEmpty()){
|
|
||||||
/*------------------------- Bytecode Generator -> Bytecode -------------------------*/
|
/*------------------------- Bytecode Generator -> Bytecode -------------------------*/
|
||||||
// Use the ByteCodeGenerator to generate bytecode from the typed AST and output it to the specified directory
|
// Use the ByteCodeGenerator to generate bytecode from the typed AST and output it to the specified directory
|
||||||
|
ByteCodeGenerator byteCodeGenerator = new ByteCodeGenerator(outputDirectoryPath, true, true);
|
||||||
final boolean genJar = Optional.ofNullable(System.getProperty("genJar")).map(String::toLowerCase).map(Boolean::parseBoolean).orElse(true);
|
assert abstractSyntaxTree != null;
|
||||||
final boolean genClass = Optional.ofNullable(System.getProperty("genClass")).map(String::toLowerCase).map(Boolean::parseBoolean).orElse(true);
|
byteCodeGenerator.visit((ProgramNode) abstractSyntaxTree);
|
||||||
|
|
||||||
ByteCodeGenerator byteCodeGenerator = new ByteCodeGenerator(outputDirectoryPath, genJar, genClass);
|
|
||||||
assert typedAst != null;
|
|
||||||
byteCodeGenerator.visit((ProgramNode) typedAst);
|
|
||||||
// Log the bytecode generation
|
// Log the bytecode generation
|
||||||
MiniCompilerLogger.logBytecodeGenerator();
|
RaupenLogger.logBytecodeGenerator();
|
||||||
} else {
|
|
||||||
for(Exception exception : SemanticAnalyzer.errors){
|
|
||||||
exception.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -29,11 +29,11 @@ import java.util.logging.*;
|
|||||||
* <code>consoleHandler.setLevel(Level.OFF);</code>
|
* <code>consoleHandler.setLevel(Level.OFF);</code>
|
||||||
* <code>fileHandler.setLevel(Level.ALL);</code>
|
* <code>fileHandler.setLevel(Level.ALL);</code>
|
||||||
*/
|
*/
|
||||||
public class MiniCompilerLogger {
|
public class RaupenLogger {
|
||||||
|
|
||||||
static Logger logger = Logger.getLogger("miniCompilerLogs");
|
static Logger logger = Logger.getLogger("RaupenLogs");
|
||||||
|
|
||||||
public MiniCompilerLogger() {
|
public RaupenLogger() {
|
||||||
// ------------------------- Logging -------------------------
|
// ------------------------- Logging -------------------------
|
||||||
logger.setLevel(Level.ALL);
|
logger.setLevel(Level.ALL);
|
||||||
logger.getParent().getHandlers()[0].setLevel(Level.ALL);
|
logger.getParent().getHandlers()[0].setLevel(Level.ALL);
|
||||||
@@ -66,7 +66,7 @@ public class MiniCompilerLogger {
|
|||||||
logger.addHandler(consoleHandler);
|
logger.addHandler(consoleHandler);
|
||||||
|
|
||||||
// Configure file handler
|
// Configure file handler
|
||||||
Handler fileHandler = new FileHandler("src/main/resources/logs/miniCompiler.log");
|
Handler fileHandler = new FileHandler("src/main/resources/logs/RaupenLog.log");
|
||||||
// Toggle file logging on/off
|
// Toggle file logging on/off
|
||||||
fileHandler.setLevel(Level.ALL);
|
fileHandler.setLevel(Level.ALL);
|
||||||
fileHandler.setFormatter(new CustomFormatter());
|
fileHandler.setFormatter(new CustomFormatter());
|
||||||
@@ -117,7 +117,7 @@ public class MiniCompilerLogger {
|
|||||||
public static void logBytecodeGenerator() {
|
public static void logBytecodeGenerator() {
|
||||||
// Printing the bytecode
|
// Printing the bytecode
|
||||||
logger.info("-------------------- Bytecode Generator -> Bytecode --------------------");
|
logger.info("-------------------- Bytecode Generator -> Bytecode --------------------");
|
||||||
logger.info("Bytecode generated without errors.");
|
logger.info("Bytecode generated");
|
||||||
logger.info("\n");
|
logger.info("\n");
|
||||||
}
|
}
|
||||||
|
|
@@ -211,8 +211,8 @@ public class ASTBuilder extends SimpleJavaBaseVisitor<ASTNode> {
|
|||||||
|
|
||||||
WhileNode While = new WhileNode(condition, doBlock);
|
WhileNode While = new WhileNode(condition, doBlock);
|
||||||
BlockNode resultBlock = new BlockNode();
|
BlockNode resultBlock = new BlockNode();
|
||||||
resultBlock.addStatement(doBlock);
|
resultBlock.addStatement((IStatementNode) doBlock);
|
||||||
resultBlock.addStatement(While);
|
resultBlock.addStatement((IStatementNode) While);
|
||||||
|
|
||||||
return resultBlock;
|
return resultBlock;
|
||||||
}
|
}
|
||||||
@@ -253,7 +253,7 @@ public class ASTBuilder extends SimpleJavaBaseVisitor<ASTNode> {
|
|||||||
|
|
||||||
// Prä-Inkrement: Das Inkrement kommt vor dem Block
|
// Prä-Inkrement: Das Inkrement kommt vor dem Block
|
||||||
if (crement != null && isPrefix) {
|
if (crement != null && isPrefix) {
|
||||||
whileBody.addStatement(crement);
|
whileBody.addStatement((IStatementNode) crement);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Block Statements der For-Schleife in den While-Block kopieren
|
// Block Statements der For-Schleife in den While-Block kopieren
|
||||||
@@ -263,7 +263,7 @@ public class ASTBuilder extends SimpleJavaBaseVisitor<ASTNode> {
|
|||||||
|
|
||||||
// Post-Inkrement: Das Inkrement kommt nach dem Block
|
// Post-Inkrement: Das Inkrement kommt nach dem Block
|
||||||
if (crement != null && !isPrefix) {
|
if (crement != null && !isPrefix) {
|
||||||
whileBody.addStatement(crement);
|
whileBody.addStatement((IStatementNode) crement);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Bedingung der While-Schleife
|
// Bedingung der While-Schleife
|
||||||
@@ -273,7 +273,7 @@ public class ASTBuilder extends SimpleJavaBaseVisitor<ASTNode> {
|
|||||||
|
|
||||||
BlockNode resultBlock = new BlockNode();
|
BlockNode resultBlock = new BlockNode();
|
||||||
for (IStatementNode statement : statements) {
|
for (IStatementNode statement : statements) {
|
||||||
resultBlock.addStatement(statement);
|
resultBlock.addStatement((IStatementNode) statement);
|
||||||
}
|
}
|
||||||
|
|
||||||
return resultBlock;
|
return resultBlock;
|
||||||
@@ -281,13 +281,8 @@ public class ASTBuilder extends SimpleJavaBaseVisitor<ASTNode> {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ASTNode visitIfElseStatement(SimpleJavaParser.IfElseStatementContext ctx) {
|
public ASTNode visitIfElseStatement(SimpleJavaParser.IfElseStatementContext ctx) {
|
||||||
IfElseNode ifElseStatementNode;
|
IfElseNode ifElseStatementNode = new IfElseNode((IfNode) visit(ctx.ifStatement()),
|
||||||
if(ctx.elseStatement() != null) {
|
|
||||||
ifElseStatementNode = new IfElseNode((IfNode) visit(ctx.ifStatement()),
|
|
||||||
(ElseNode) visit(ctx.elseStatement()));
|
(ElseNode) visit(ctx.elseStatement()));
|
||||||
} else {
|
|
||||||
ifElseStatementNode = new IfElseNode((IfNode) visit(ctx.ifStatement()), null);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (SimpleJavaParser.ElseIfStatementContext elseIf : ctx.elseIfStatement()){
|
for (SimpleJavaParser.ElseIfStatementContext elseIf : ctx.elseIfStatement()){
|
||||||
ifElseStatementNode.addElseIfStatement(((IfNode) visit(elseIf)));
|
ifElseStatementNode.addElseIfStatement(((IfNode) visit(elseIf)));
|
||||||
@@ -559,9 +554,9 @@ public class ASTBuilder extends SimpleJavaBaseVisitor<ASTNode> {
|
|||||||
@Override
|
@Override
|
||||||
public ASTNode visitDotExpression(SimpleJavaParser.DotExpressionContext ctx) {
|
public ASTNode visitDotExpression(SimpleJavaParser.DotExpressionContext ctx) {
|
||||||
if(ctx.dotExpression() != null) {
|
if(ctx.dotExpression() != null) {
|
||||||
return new DotNode((DotNode) visit(ctx.dotExpression()), ctx.DotOperator().getText(), (DotSubtractionNode) visit(ctx.dotSubtractionExpression()));
|
return new DotNode((DotNode) visit(ctx.dotExpression()), ctx.DotOperator().getText(), (DotSubstractionNode) visit(ctx.dotSubtractionExpression()));
|
||||||
} else if(ctx.dotSubtractionExpression() != null) {
|
} else if(ctx.dotSubtractionExpression() != null) {
|
||||||
return new DotNode((DotSubtractionNode) visit(ctx.dotSubtractionExpression()));
|
return new DotNode((DotSubstractionNode) visit(ctx.dotSubtractionExpression()));
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -569,13 +564,13 @@ public class ASTBuilder extends SimpleJavaBaseVisitor<ASTNode> {
|
|||||||
@Override
|
@Override
|
||||||
public ASTNode visitDotSubtractionExpression(SimpleJavaParser.DotSubtractionExpressionContext ctx) {
|
public ASTNode visitDotSubtractionExpression(SimpleJavaParser.DotSubtractionExpressionContext ctx) {
|
||||||
if(ctx.IntValue() != null) {
|
if(ctx.IntValue() != null) {
|
||||||
return new DotSubtractionNode(new ValueNode(EnumValueNode.INT_VALUE, ctx.IntValue().getText()));
|
return new DotSubstractionNode(new ValueNode(EnumValueNode.INT_VALUE, ctx.IntValue().getText()));
|
||||||
} else if(ctx.Identifier() != null) {
|
} else if(ctx.Identifier() != null) {
|
||||||
return new DotSubtractionNode(ctx.Identifier().getText());
|
return new DotSubstractionNode(ctx.Identifier().getText());
|
||||||
} else if(ctx.memberAccess() != null) {
|
} else if(ctx.memberAccess() != null) {
|
||||||
return new DotSubtractionNode((MemberAccessNode) visit(ctx.memberAccess()));
|
return new DotSubstractionNode((MemberAccessNode) visit(ctx.memberAccess()));
|
||||||
} else if(ctx.methodCall() != null && ctx.calculationExpression() != null) {
|
} else if(ctx.methodCall() != null && ctx.calculationExpression() != null) {
|
||||||
return new DotSubtractionNode((MethodCallNode) visit(ctx.methodCall()), (CalculationNode) visit(ctx.calculationExpression()));
|
return new DotSubstractionNode((MethodCallNode) visit(ctx.methodCall()), (CalculationNode) visit(ctx.calculationExpression()));
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -604,4 +599,6 @@ public class ASTBuilder extends SimpleJavaBaseVisitor<ASTNode> {
|
|||||||
default -> new ReferenceType(identifier);
|
default -> new ReferenceType(identifier);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
File diff suppressed because one or more lines are too long
@@ -1,4 +1,4 @@
|
|||||||
// Generated from C:/Users/Maxi/Documents/DHBW/Compilerbau/NichtHaskell2.0/src/main/java/parser/grammar/SimpleJava.g4 by ANTLR 4.13.1
|
// Generated from C:/Users/janni/Desktop/NichtHaskell2.0/src/main/java/parser/grammar/SimpleJava.g4 by ANTLR 4.13.1
|
||||||
package parser.generated;
|
package parser.generated;
|
||||||
|
|
||||||
import org.antlr.v4.runtime.ParserRuleContext;
|
import org.antlr.v4.runtime.ParserRuleContext;
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
// Generated from C:/Users/Maxi/Documents/DHBW/Compilerbau/NichtHaskell2.0/src/main/java/parser/grammar/SimpleJava.g4 by ANTLR 4.13.1
|
// Generated from C:/Users/janni/Desktop/NichtHaskell2.0/src/main/java/parser/grammar/SimpleJava.g4 by ANTLR 4.13.1
|
||||||
package parser.generated;
|
package parser.generated;
|
||||||
import org.antlr.v4.runtime.tree.AbstractParseTreeVisitor;
|
import org.antlr.v4.runtime.tree.AbstractParseTreeVisitor;
|
||||||
|
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
// Generated from C:/Users/Maxi/Documents/DHBW/Compilerbau/NichtHaskell2.0/src/main/java/parser/grammar/SimpleJava.g4 by ANTLR 4.13.1
|
// Generated from C:/Users/janni/Desktop/NichtHaskell2.0/src/main/java/parser/grammar/SimpleJava.g4 by ANTLR 4.13.1
|
||||||
package parser.generated;
|
package parser.generated;
|
||||||
import org.antlr.v4.runtime.Lexer;
|
import org.antlr.v4.runtime.Lexer;
|
||||||
import org.antlr.v4.runtime.CharStream;
|
import org.antlr.v4.runtime.CharStream;
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
// Generated from C:/Users/Maxi/Documents/DHBW/Compilerbau/NichtHaskell2.0/src/main/java/parser/grammar/SimpleJava.g4 by ANTLR 4.13.1
|
// Generated from C:/Users/janni/Desktop/NichtHaskell2.0/src/main/java/parser/grammar/SimpleJava.g4 by ANTLR 4.13.1
|
||||||
package parser.generated;
|
package parser.generated;
|
||||||
import org.antlr.v4.runtime.tree.ParseTreeListener;
|
import org.antlr.v4.runtime.tree.ParseTreeListener;
|
||||||
|
|
||||||
|
File diff suppressed because it is too large
Load Diff
@@ -1,4 +1,4 @@
|
|||||||
// Generated from C:/Users/Maxi/Documents/DHBW/Compilerbau/NichtHaskell2.0/src/main/java/parser/grammar/SimpleJava.g4 by ANTLR 4.13.1
|
// Generated from C:/Users/janni/Desktop/NichtHaskell2.0/src/main/java/parser/grammar/SimpleJava.g4 by ANTLR 4.13.1
|
||||||
package parser.generated;
|
package parser.generated;
|
||||||
import org.antlr.v4.runtime.tree.ParseTreeVisitor;
|
import org.antlr.v4.runtime.tree.ParseTreeVisitor;
|
||||||
|
|
||||||
|
@@ -8,7 +8,7 @@ import java.util.Stack;
|
|||||||
|
|
||||||
public class Scope {
|
public class Scope {
|
||||||
|
|
||||||
private final Stack<HashMap<String, ITypeNode>> localVars;
|
private Stack<HashMap<String, ITypeNode>> localVars;
|
||||||
|
|
||||||
public Scope() {
|
public Scope() {
|
||||||
localVars = new Stack<HashMap<String, ITypeNode>>();
|
localVars = new Stack<HashMap<String, ITypeNode>>();
|
||||||
|
@@ -21,7 +21,6 @@ import ast.statementexpressions.AssignableNode;
|
|||||||
import ast.statementexpressions.NewDeclarationNode;
|
import ast.statementexpressions.NewDeclarationNode;
|
||||||
import ast.statementexpressions.crementexpressions.DecrementNode;
|
import ast.statementexpressions.crementexpressions.DecrementNode;
|
||||||
import ast.statementexpressions.crementexpressions.IncrementNode;
|
import ast.statementexpressions.crementexpressions.IncrementNode;
|
||||||
import ast.statementexpressions.methodcallstatementnexpressions.ChainedMethodNode;
|
|
||||||
import ast.statementexpressions.methodcallstatementnexpressions.MethodCallNode;
|
import ast.statementexpressions.methodcallstatementnexpressions.MethodCallNode;
|
||||||
import ast.statementexpressions.methodcallstatementnexpressions.TargetNode;
|
import ast.statementexpressions.methodcallstatementnexpressions.TargetNode;
|
||||||
import ast.statements.*;
|
import ast.statements.*;
|
||||||
@@ -30,10 +29,9 @@ import ast.type.EnumAccessModifierNode;
|
|||||||
import ast.type.ValueNode;
|
import ast.type.ValueNode;
|
||||||
import ast.type.type.*;
|
import ast.type.type.*;
|
||||||
import com.sun.jdi.IntegerType;
|
import com.sun.jdi.IntegerType;
|
||||||
import semantic.context.ClassContext;
|
|
||||||
import semantic.context.Context;
|
import semantic.context.Context;
|
||||||
import semantic.exceptions.*;
|
import semantic.exceptions.*;
|
||||||
import semantic.TypeCheckResult;
|
import typechecker.TypeCheckResult;
|
||||||
|
|
||||||
public class SemanticAnalyzer implements SemanticVisitor {
|
public class SemanticAnalyzer implements SemanticVisitor {
|
||||||
|
|
||||||
@@ -165,11 +163,6 @@ public class SemanticAnalyzer implements SemanticVisitor {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TypeCheckResult analyze(FieldNode toCheck) {
|
public TypeCheckResult analyze(FieldNode toCheck) {
|
||||||
if (toCheck.type instanceof ReferenceType referenceType) {
|
|
||||||
if (!context.containsClass(referenceType.getIdentifier())) {
|
|
||||||
errors.add(new NotDeclaredException(referenceType.getIdentifier() + " not declared"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (currentFields.get(toCheck.identifier) != null) {
|
if (currentFields.get(toCheck.identifier) != null) {
|
||||||
errors.add(new AlreadyDeclaredException("Already declared " + toCheck.identifier));
|
errors.add(new AlreadyDeclaredException("Already declared " + toCheck.identifier));
|
||||||
return new TypeCheckResult(false, null);
|
return new TypeCheckResult(false, null);
|
||||||
@@ -177,8 +170,6 @@ public class SemanticAnalyzer implements SemanticVisitor {
|
|||||||
currentFields.put(toCheck.identifier, toCheck.type);
|
currentFields.put(toCheck.identifier, toCheck.type);
|
||||||
}
|
}
|
||||||
return new TypeCheckResult(true, null);
|
return new TypeCheckResult(true, null);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -253,16 +244,11 @@ public class SemanticAnalyzer implements SemanticVisitor {
|
|||||||
|
|
||||||
if (toCheck.memberAccess != null) {
|
if (toCheck.memberAccess != null) {
|
||||||
var result = toCheck.memberAccess.accept(this);
|
var result = toCheck.memberAccess.accept(this);
|
||||||
toCheck.identifier = toCheck.memberAccess.identifiers.getLast();
|
|
||||||
toCheck.setTypeNode(result.getType());
|
toCheck.setTypeNode(result.getType());
|
||||||
return result;
|
return result;
|
||||||
} else {
|
} else {
|
||||||
if (currentFields.get(toCheck.identifier) != null) {
|
if (currentFields.get(toCheck.identifier) != null) {
|
||||||
var type = currentFields.get(toCheck.identifier);
|
var type = currentFields.get(toCheck.identifier);
|
||||||
MemberAccessNode memberAccessNode = new MemberAccessNode(false);
|
|
||||||
memberAccessNode.identifiers.add(currentClass.identifier);
|
|
||||||
memberAccessNode.identifiers.add(toCheck.identifier);
|
|
||||||
toCheck.memberAccess = memberAccessNode;
|
|
||||||
toCheck.setTypeNode(type);
|
toCheck.setTypeNode(type);
|
||||||
return new TypeCheckResult(true, type);
|
return new TypeCheckResult(true, type);
|
||||||
} else if (currentScope.getLocalVar(toCheck.identifier) != null) {
|
} else if (currentScope.getLocalVar(toCheck.identifier) != null) {
|
||||||
@@ -289,6 +275,13 @@ public class SemanticAnalyzer implements SemanticVisitor {
|
|||||||
currentNullType = oldNullType;
|
currentNullType = oldNullType;
|
||||||
var valid = true;
|
var valid = true;
|
||||||
|
|
||||||
|
// This check currently handles things like :
|
||||||
|
/**
|
||||||
|
* private int i;
|
||||||
|
* void foo(int i){
|
||||||
|
* i = i;
|
||||||
|
* }
|
||||||
|
*/
|
||||||
if (assignable.equals(rExpression)) {
|
if (assignable.equals(rExpression)) {
|
||||||
errors.add(new TypeMismatchException("Cannot assign to self"));
|
errors.add(new TypeMismatchException("Cannot assign to self"));
|
||||||
valid = false;
|
valid = false;
|
||||||
@@ -317,40 +310,20 @@ 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
|
||||||
public TypeCheckResult analyze(MethodCallNode toCheck) {
|
public TypeCheckResult analyze(MethodCallNode toCheck) {
|
||||||
|
|
||||||
if (toCheck.target != null) {
|
|
||||||
if(toCheck.target.memberAccess == null){
|
|
||||||
MemberAccessNode memberAccessNode = new MemberAccessNode(false);
|
|
||||||
memberAccessNode.identifiers.add(currentClass.identifier);
|
|
||||||
memberAccessNode.identifiers.add(toCheck.target.identifier);
|
|
||||||
toCheck.target.memberAccess = memberAccessNode;
|
|
||||||
}
|
|
||||||
if (toCheck.target.identifier != null) {
|
if (toCheck.target.identifier != null) {
|
||||||
var targetType = currentScope.getLocalVar(toCheck.target.identifier);
|
var targetType = currentScope.getLocalVar(toCheck.target.identifier);
|
||||||
if (targetType == null) {
|
if (targetType == null) {
|
||||||
targetType = currentFields.get(toCheck.target.identifier);
|
targetType = currentFields.get(toCheck.target.identifier);
|
||||||
}
|
}
|
||||||
if (targetType instanceof ReferenceType reference) {
|
if (targetType instanceof ReferenceType reference) {
|
||||||
if (!toCheck.chainedMethods.isEmpty()) {
|
|
||||||
for (ChainedMethodNode chainedMethod : toCheck.chainedMethods) {
|
|
||||||
var type = getTypeFromMethod(chainedMethod, reference);
|
|
||||||
if (type instanceof ReferenceType referenceType)
|
|
||||||
reference = referenceType;
|
|
||||||
else
|
|
||||||
errors.add(new TypeMismatchException("Ein Basetyp hat keine funktionen"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
var type = getTypeFromMethod(toCheck, reference);
|
var type = getTypeFromMethod(toCheck, reference);
|
||||||
if (type != null) {
|
if (type != null) {
|
||||||
return new TypeCheckResult(true, type);
|
return new TypeCheckResult(true, type);
|
||||||
@@ -360,13 +333,11 @@ public class SemanticAnalyzer implements SemanticVisitor {
|
|||||||
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (toCheck.target.thisTar != null) {
|
|
||||||
if (toCheck.target.thisTar) {
|
if (toCheck.target.thisTar) {
|
||||||
var type = getTypeFromMethod(toCheck, new ReferenceType(currentClass.identifier));
|
var type = getTypeFromMethod(toCheck, new ReferenceType(currentClass.identifier));
|
||||||
if (type != null) {
|
if (type != null) {
|
||||||
return new TypeCheckResult(true, type);
|
return new TypeCheckResult(true, type);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
var result = toCheck.target.accept(this);
|
var result = toCheck.target.accept(this);
|
||||||
if (result.getType() instanceof ReferenceType reference) {
|
if (result.getType() instanceof ReferenceType reference) {
|
||||||
@@ -374,27 +345,6 @@ public class SemanticAnalyzer implements SemanticVisitor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
|
|
||||||
ReferenceType reference = new ReferenceType(currentClass.identifier);
|
|
||||||
if (!toCheck.chainedMethods.isEmpty()) {
|
|
||||||
for (ChainedMethodNode chainedMethod : toCheck.chainedMethods) {
|
|
||||||
var type = getTypeFromMethod(chainedMethod, reference);
|
|
||||||
if (type instanceof ReferenceType referenceType)
|
|
||||||
reference = referenceType;
|
|
||||||
else
|
|
||||||
errors.add(new TypeMismatchException("Ein Basetyp hat keine funktionen"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
var type = getTypeFromMethod(toCheck, reference);
|
|
||||||
if (type != null) {
|
|
||||||
return new TypeCheckResult(true, type);
|
|
||||||
} else {
|
|
||||||
return new TypeCheckResult(false, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
return new TypeCheckResult(false, null);
|
return new TypeCheckResult(false, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -433,9 +383,9 @@ public class SemanticAnalyzer implements SemanticVisitor {
|
|||||||
|
|
||||||
if (context.containsClass(toCheck.identifier)) {
|
if (context.containsClass(toCheck.identifier)) {
|
||||||
return new TypeCheckResult(true, new ReferenceType(toCheck.identifier));
|
return new TypeCheckResult(true, new ReferenceType(toCheck.identifier));
|
||||||
} else {
|
|
||||||
throw new RuntimeException("Cannot find class " + toCheck.identifier);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -459,7 +409,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;
|
||||||
@@ -467,12 +416,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,46 +427,28 @@ public class SemanticAnalyzer implements SemanticVisitor {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TypeCheckResult analyze(DotNode toCheck) {
|
public TypeCheckResult analyze(DotNode toCheck) {
|
||||||
if (toCheck.dotSubtractionExpression != null) {
|
if (toCheck.dotSubstractionExpression != null) {
|
||||||
var result = toCheck.dotSubtractionExpression.accept(this);
|
return toCheck.dotSubstractionExpression.accept(this);
|
||||||
toCheck.setType(result.getType());
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
return new TypeCheckResult(false, null);
|
return new TypeCheckResult(false, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TypeCheckResult analyze(DotSubtractionNode 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;
|
||||||
}
|
}
|
||||||
@@ -539,8 +468,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"));
|
||||||
@@ -564,17 +493,9 @@ 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);
|
return new TypeCheckResult(valid, currentFields.get(unary.identifier));
|
||||||
memberAccessNode.identifiers.add(currentClass.identifier);
|
|
||||||
memberAccessNode.identifiers.add(unary.identifier);
|
|
||||||
unary.memberAccess = memberAccessNode;
|
|
||||||
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());
|
||||||
@@ -584,19 +505,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());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -607,20 +524,8 @@ public class SemanticAnalyzer implements SemanticVisitor {
|
|||||||
public TypeCheckResult analyze(MemberAccessNode memberAccessNode) {
|
public TypeCheckResult analyze(MemberAccessNode memberAccessNode) {
|
||||||
|
|
||||||
ITypeNode currentType = null;
|
ITypeNode currentType = null;
|
||||||
int start = 0;
|
|
||||||
if(!memberAccessNode.identifiers.isEmpty()){
|
|
||||||
if(currentFields.get(memberAccessNode.identifiers.getFirst()) != null){
|
|
||||||
memberAccessNode.identifiers.addFirst(currentClass.identifier);
|
|
||||||
start++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(context.getClasses().get(memberAccessNode.identifiers.getFirst()) == null){
|
|
||||||
memberAccessNode.identifiers.addFirst(currentClass.identifier);
|
|
||||||
start++;
|
|
||||||
}
|
|
||||||
for (int i = start; i < memberAccessNode.identifiers.size(); i++) {
|
|
||||||
|
|
||||||
String s = memberAccessNode.identifiers.get(i);
|
for (String s : memberAccessNode.identifiers) {
|
||||||
if (currentType == null) {
|
if (currentType == null) {
|
||||||
if (currentScope.getLocalVar(s) != null) {
|
if (currentScope.getLocalVar(s) != null) {
|
||||||
currentType = currentScope.getLocalVar(s);
|
currentType = currentScope.getLocalVar(s);
|
||||||
@@ -635,8 +540,7 @@ public class SemanticAnalyzer implements SemanticVisitor {
|
|||||||
} else {
|
} else {
|
||||||
if (currentType instanceof ReferenceType reference) {
|
if (currentType instanceof ReferenceType reference) {
|
||||||
var currentTypeClass = context.getClass(reference.getIdentifier());
|
var currentTypeClass = context.getClass(reference.getIdentifier());
|
||||||
memberAccessNode.identifiers.add(i, reference.getIdentifier());
|
|
||||||
i++;
|
|
||||||
var currentField = currentTypeClass.getField(s);
|
var currentField = currentTypeClass.getField(s);
|
||||||
if (currentField.getAccessModifier().accessType == EnumAccessModifierNode.PUBLIC) {
|
if (currentField.getAccessModifier().accessType == EnumAccessModifierNode.PUBLIC) {
|
||||||
currentType = currentField.getType();
|
currentType = currentField.getType();
|
||||||
@@ -657,11 +561,6 @@ public class SemanticAnalyzer implements SemanticVisitor {
|
|||||||
|
|
||||||
if (targetNode.memberAccess != null) {
|
if (targetNode.memberAccess != null) {
|
||||||
return targetNode.memberAccess.accept(this);
|
return targetNode.memberAccess.accept(this);
|
||||||
} else if(targetNode.identifier != null) {
|
|
||||||
MemberAccessNode memberAccessNode = new MemberAccessNode(false);
|
|
||||||
memberAccessNode.identifiers.add(currentClass.identifier);
|
|
||||||
memberAccessNode.identifiers.add(targetNode.identifier);
|
|
||||||
targetNode.memberAccess = memberAccessNode;
|
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -721,37 +620,4 @@ public class SemanticAnalyzer implements SemanticVisitor {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private ITypeNode getTypeFromMethod(ChainedMethodNode toCheck, ReferenceType reference) {
|
|
||||||
var classContext = context.getClass(reference.getIdentifier());
|
|
||||||
|
|
||||||
var methods = classContext.getMethods();
|
|
||||||
for (var method : methods) {
|
|
||||||
if (toCheck.identifier.equals(method.getIdentifier())) {
|
|
||||||
if (method.getParameters().size() == toCheck.expressions.size() && !(method instanceof ConstructorNode)) {
|
|
||||||
boolean same = true;
|
|
||||||
for (int i = 0; i < method.getParameters().size(); i++) {
|
|
||||||
var result1 = method.getParameters().get(i).accept(this);
|
|
||||||
var result2 = toCheck.expressions.get(i).accept(this);
|
|
||||||
if (!Objects.equals(result1.getType(), result2.getType())) {
|
|
||||||
same = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (same) {
|
|
||||||
if (method.accesModifier.accessType == EnumAccessModifierNode.PUBLIC) {
|
|
||||||
if (method.getType() == null) {
|
|
||||||
return new BaseType(TypeEnum.VOID);
|
|
||||||
}
|
|
||||||
return method.getType();
|
|
||||||
} else {
|
|
||||||
errors.add(new NotVisibleException("This Method is not Visible"));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
@@ -15,6 +15,7 @@ import ast.statementexpressions.methodcallstatementnexpressions.MethodCallNode;
|
|||||||
import ast.statementexpressions.methodcallstatementnexpressions.TargetNode;
|
import ast.statementexpressions.methodcallstatementnexpressions.TargetNode;
|
||||||
import ast.statements.*;
|
import ast.statements.*;
|
||||||
import ast.type.ValueNode;
|
import ast.type.ValueNode;
|
||||||
|
import typechecker.TypeCheckResult;
|
||||||
|
|
||||||
public interface SemanticVisitor {
|
public interface SemanticVisitor {
|
||||||
|
|
||||||
@@ -60,7 +61,7 @@ public interface SemanticVisitor {
|
|||||||
|
|
||||||
TypeCheckResult analyze(DotNode toCheck);
|
TypeCheckResult analyze(DotNode toCheck);
|
||||||
|
|
||||||
TypeCheckResult analyze(DotSubtractionNode toCheck);
|
TypeCheckResult analyze(DotSubstractionNode toCheck);
|
||||||
|
|
||||||
TypeCheckResult analyze(NonCalculationNode toCheck);
|
TypeCheckResult analyze(NonCalculationNode toCheck);
|
||||||
|
|
||||||
|
@@ -9,8 +9,8 @@ import java.util.HashMap;
|
|||||||
|
|
||||||
public class ClassContext {
|
public class ClassContext {
|
||||||
|
|
||||||
private final HashMap<String, FieldContext> fields;
|
private HashMap<String, FieldContext> fields;
|
||||||
private final ArrayList<MethodNode> methods = new ArrayList<>();
|
private ArrayList<MethodNode> methods = new ArrayList<>();
|
||||||
|
|
||||||
public ClassContext(ClassNode classNode) {
|
public ClassContext(ClassNode classNode) {
|
||||||
|
|
||||||
|
@@ -5,7 +5,7 @@ import java.util.HashMap;
|
|||||||
|
|
||||||
public class Context {
|
public class Context {
|
||||||
|
|
||||||
private final HashMap<String, ClassContext> classes;
|
private HashMap<String, ClassContext> classes;
|
||||||
|
|
||||||
public Context(ProgramNode programNode) {
|
public Context(ProgramNode programNode) {
|
||||||
classes = new HashMap<>();
|
classes = new HashMap<>();
|
||||||
@@ -21,10 +21,6 @@ public class Context {
|
|||||||
return classes.get(identifier);
|
return classes.get(identifier);
|
||||||
}
|
}
|
||||||
|
|
||||||
public HashMap<String, ClassContext> getClasses() {
|
|
||||||
return classes;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean containsClass(String identifier) {
|
public boolean containsClass(String identifier) {
|
||||||
return classes.containsKey(identifier);
|
return classes.containsKey(identifier);
|
||||||
}
|
}
|
||||||
|
@@ -6,8 +6,8 @@ import ast.type.type.*;
|
|||||||
|
|
||||||
public class FieldContext {
|
public class FieldContext {
|
||||||
|
|
||||||
private final AccessModifierNode accessModifier;
|
private AccessModifierNode accessModifier;
|
||||||
private final ITypeNode type;
|
private ITypeNode type;
|
||||||
|
|
||||||
public FieldContext(FieldNode field) {
|
public FieldContext(FieldNode field) {
|
||||||
accessModifier = field.accessTypeNode;
|
accessModifier = field.accessTypeNode;
|
||||||
|
@@ -1,12 +1,12 @@
|
|||||||
package semantic;
|
package typechecker;
|
||||||
|
|
||||||
|
|
||||||
import ast.type.type.ITypeNode;
|
import ast.type.type.ITypeNode;
|
||||||
|
|
||||||
public class TypeCheckResult {
|
public class TypeCheckResult {
|
||||||
|
|
||||||
private final boolean valid;
|
private boolean valid;
|
||||||
private final ITypeNode type;
|
private ITypeNode type;
|
||||||
|
|
||||||
public TypeCheckResult(boolean valid, ITypeNode type) {
|
public TypeCheckResult(boolean valid, ITypeNode type) {
|
||||||
this.valid = valid;
|
this.valid = valid;
|
@@ -4,7 +4,7 @@ import bytecode.visitor.ClassVisitor;
|
|||||||
import bytecode.visitor.MethodVisitor;
|
import bytecode.visitor.MethodVisitor;
|
||||||
import bytecode.visitor.ProgramVisitor;
|
import bytecode.visitor.ProgramVisitor;
|
||||||
import semantic.SemanticVisitor;
|
import semantic.SemanticVisitor;
|
||||||
import semantic.TypeCheckResult;
|
import typechecker.TypeCheckResult;
|
||||||
|
|
||||||
public interface Visitable {
|
public interface Visitable {
|
||||||
default void accept(ProgramVisitor programVisitor) {
|
default void accept(ProgramVisitor programVisitor) {
|
||||||
|
@@ -1,3 +0,0 @@
|
|||||||
Manifest-Version: 1.0
|
|
||||||
Main-Class: main.Main
|
|
||||||
|
|
@@ -2,6 +2,9 @@ public class Compiler {
|
|||||||
public int add(int i, int j) {
|
public int add(int i, int j) {
|
||||||
return i+j;
|
return i+j;
|
||||||
}
|
}
|
||||||
|
public static void main(String[] args) {
|
||||||
|
int a = 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class Node {
|
public class Node {
|
||||||
|
BIN
src/main/resources/output/output.jar
Normal file
BIN
src/main/resources/output/output.jar
Normal file
Binary file not shown.
@@ -2,17 +2,23 @@
|
|||||||
### IntelliJs play buttons do not work. Run in "src/test" folder with "make" command to run all
|
### IntelliJs play buttons do not work. Run in "src/test" folder with "make" command to run all
|
||||||
### Or run only parts with "make compile-javac", "make clean" etc.
|
### Or run only parts with "make compile-javac", "make clean" etc.
|
||||||
|
|
||||||
all: compile-javac compile-miniCompiler
|
all: compile-javac compile-raupenpiler
|
||||||
|
|
||||||
compile-javac:
|
compile-javac:
|
||||||
javac -d .\resources\output\javac .\resources\input\CompilerInput.java
|
javac -d .\resources\output\javac .\resources\input\CompilerInput.java
|
||||||
|
|
||||||
compile-miniCompiler:
|
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 -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/miniCompiler
|
# cp ../main/resources/output/CompilerInput.class .java/resources/output/raupenpiler
|
||||||
|
|
||||||
test-miniCompiler:
|
test: compile-javac compile-raupenpiler test-javac test-raupenpiler
|
||||||
|
|
||||||
|
test-javac:
|
||||||
|
# gleich wie bei raupenpiler, kann ich ohne funktionierenden Compiler nicht testen
|
||||||
|
|
||||||
|
|
||||||
|
test-raupenpiler:
|
||||||
# move the compiled class to the test/main folder
|
# move the compiled class to the test/main folder
|
||||||
mv ../main/resources/output/CompilerInput.class .java/main/
|
mv ../main/resources/output/CompilerInput.class .java/main/
|
||||||
# compile the test class
|
# compile the test class
|
||||||
@@ -23,19 +29,15 @@ test-miniCompiler:
|
|||||||
|
|
||||||
|
|
||||||
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/miniCompiler/*.class
|
rm -f ./resources/output/raupenpiler/*.class
|
||||||
rm -f ./resources/output/miniCompiler/*.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/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 featureTests
|
||||||
rm -f ./resources/input/*/*.class
|
rm -f ./resources/input/featureTests/*.class
|
||||||
# clean test results from maven surefire plugin
|
|
||||||
rm -f ../../target/surefire-reports/*.txt
|
|
||||||
|
|
||||||
|
File diff suppressed because it is too large
Load Diff
@@ -11,6 +11,8 @@ package main;
|
|||||||
* Wenn unser Compiler funktioniert, sollten keine Errors kommen (sondern nur die Ausgaben, die wir in der CompilerInput.java Datei gemacht haben,
|
* Wenn unser Compiler funktioniert, sollten keine Errors kommen (sondern nur die Ausgaben, die wir in der CompilerInput.java Datei gemacht haben,
|
||||||
* oder Methoden, die wir hier aufrufen).</p>
|
* oder Methoden, die wir hier aufrufen).</p>
|
||||||
*
|
*
|
||||||
|
* <p><strong>PROBLEM:</strong> Hier kommen Errors, was eigentlich heißt, dass der Compiler nicht funktioniert, der Test sollte eigentlich passen.
|
||||||
|
* <br><strong>DENN:</strong> Wenn ich statt unserem CompilerInput.class die CompilerInput.class von javac verwende (aus <code> src/test/resources/output/javac </code>), dann funktioniert es.</p>
|
||||||
*/
|
*/
|
||||||
public class EndToEndTester {
|
public class EndToEndTester {
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
|
48
src/test/java/main/FailureTest.java
Normal file
48
src/test/java/main/FailureTest.java
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
package main;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import javax.tools.JavaCompiler;
|
||||||
|
import javax.tools.ToolProvider;
|
||||||
|
import java.io.File;
|
||||||
|
|
||||||
|
public class FailureTest {
|
||||||
|
/**
|
||||||
|
* This test method checks if invalid Java files fail to compile as expected.
|
||||||
|
* It uses the JavaCompiler from the ToolProvider to compile the files.
|
||||||
|
* The test passes if all the files fail to compile.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void areTestFilesActuallyFailTest() {
|
||||||
|
// Get the system Java compiler
|
||||||
|
JavaCompiler javac = ToolProvider.getSystemJavaCompiler();
|
||||||
|
// Assert that the compiler is available
|
||||||
|
assertNotNull(javac, "Java Compiler is not available");
|
||||||
|
|
||||||
|
String directoryPath = "src/test/resources/input/failureTests";
|
||||||
|
File folder = new File(directoryPath);
|
||||||
|
|
||||||
|
if (folder.isDirectory()) {
|
||||||
|
File[] files = folder.listFiles((dir, name) -> name.endsWith(".java"));
|
||||||
|
|
||||||
|
if (files != null) {
|
||||||
|
for (File file : files) {
|
||||||
|
// Try to compile the file and get the result
|
||||||
|
// The run method returns 0 if the compilation was successful, and non-zero otherwise
|
||||||
|
int result = javac.run(null, null, null, file.getPath());
|
||||||
|
|
||||||
|
// Assert that the compilation failed (i.e., the result is non-zero)
|
||||||
|
assertTrue(result != 0, "Expected compilation failure for " + file.getName());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
System.out.println("No files found in the directory.");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
System.out.println("The provided path is not a directory.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
46
src/test/java/main/FeatureTest.java
Normal file
46
src/test/java/main/FeatureTest.java
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
package main;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import javax.tools.JavaCompiler;
|
||||||
|
import javax.tools.ToolProvider;
|
||||||
|
import java.io.File;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
|
|
||||||
|
public class FeatureTest {
|
||||||
|
/**
|
||||||
|
* This test method checks if valid Java files compile successfully.
|
||||||
|
* It uses the JavaCompiler from the ToolProvider to compile the files.
|
||||||
|
* The test passes if all the files compile without errors.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void areTestFilesActuallyValid() {
|
||||||
|
// Get the system Java compiler
|
||||||
|
JavaCompiler javac = ToolProvider.getSystemJavaCompiler();
|
||||||
|
// Assert that the compiler is available
|
||||||
|
assertNotNull(javac, "Java Compiler is not available");
|
||||||
|
|
||||||
|
String directoryPath = "src/test/resources/input/featureTests";
|
||||||
|
File folder = new File(directoryPath);
|
||||||
|
|
||||||
|
if (folder.isDirectory()) {
|
||||||
|
File[] files = folder.listFiles((dir, name) -> name.endsWith(".java"));
|
||||||
|
|
||||||
|
if (files != null) {
|
||||||
|
for (File file : files) {
|
||||||
|
// Try to compile the file and get the result
|
||||||
|
// The run method returns 0 if the compilation was successful, and non-zero otherwise
|
||||||
|
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 directory.");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
System.out.println("The provided path is not a directory.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -1,236 +0,0 @@
|
|||||||
package main;
|
|
||||||
|
|
||||||
import org.junit.jupiter.api.Disabled;
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
|
|
||||||
import javax.tools.JavaCompiler;
|
|
||||||
import javax.tools.ToolProvider;
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.nio.file.Files;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.*;
|
|
||||||
|
|
||||||
public class InputFilesTest {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This test method checks if valid Java files compile successfully.
|
|
||||||
* It uses the JavaCompiler from the ToolProvider to compile the files.
|
|
||||||
* The test passes if all the files compile without errors.
|
|
||||||
*/
|
|
||||||
@Test
|
|
||||||
public void areTestFilesActuallyValid() 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");
|
|
||||||
File endabgabeTests = new File("src/test/resources/input/endabgabeTests");
|
|
||||||
File singleFeatureSemanticTests = new File("src/test/resources/input/singleFeatureSemanticTests");
|
|
||||||
File singleFeatureTests = new File("src/test/resources/input/singleFeatureTests");
|
|
||||||
File typedAstFeatureTests = new File("src/test/resources/input/typedAstFeatureTests");
|
|
||||||
|
|
||||||
List<File> files = getJavaFilesFromDirectory(combinedFeatureTests);
|
|
||||||
// files.addAll(getJavaFilesFromDirectory(endabgabeTests));
|
|
||||||
// files.addAll(getJavaFilesFromDirectory(singleFeatureSemanticTests));
|
|
||||||
files.addAll(getJavaFilesFromDirectory(singleFeatureTests));
|
|
||||||
// files.addAll(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.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@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.
|
|
||||||
* It uses the JavaCompiler from the ToolProvider to compile the files.
|
|
||||||
* The test passes if all the files fail to compile.
|
|
||||||
*/
|
|
||||||
@Test
|
|
||||||
public void areTestFilesActuallyFails() 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 folder1 = new File("src/test/resources/input/failureTests");
|
|
||||||
File folder2 = new File("src/test/resources/input/typedAstExceptionsTest");
|
|
||||||
|
|
||||||
List<File> files = getJavaFilesFromDirectory(folder1);
|
|
||||||
files.addAll(getJavaFilesFromDirectory(folder2));
|
|
||||||
|
|
||||||
|
|
||||||
if (!files.isEmpty()) {
|
|
||||||
for (File file : files) {
|
|
||||||
// Try to compile the file and get the result
|
|
||||||
// The run method returns 0 if the compilation was successful, and non-zero otherwise
|
|
||||||
int result = javac.run(null, null, null, file.getPath());
|
|
||||||
|
|
||||||
// Assert that the compilation failed (i.e., the result is non-zero)
|
|
||||||
assertTrue(result != 0, "Expected compilation failure for " + file.getName());
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
System.out.println("No files found in the directory.");
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Helper method to get all .java files from a directory.
|
|
||||||
*
|
|
||||||
* @param directory the directory to search for .java files
|
|
||||||
* @return a list of .java files
|
|
||||||
* @throws IOException if an I/O error occurs
|
|
||||||
*/
|
|
||||||
private List<File> getJavaFilesFromDirectory(File directory) throws IOException {
|
|
||||||
if (directory.isDirectory()) {
|
|
||||||
return Files.list(directory.toPath())
|
|
||||||
.filter(path -> path.toString().endsWith(".java"))
|
|
||||||
.map(java.nio.file.Path::toFile)
|
|
||||||
.collect(Collectors.toList());
|
|
||||||
} else {
|
|
||||||
System.out.println("The provided path is not a directory: " + directory.getPath());
|
|
||||||
return List.of();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,21 +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 semantic.EndToTypedAstTest;
|
import org.antlr.v4.runtime.CharStreams;
|
||||||
import semantic.SemanticTest;
|
|
||||||
|
import java.io.IOException;
|
||||||
|
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,
|
|
||||||
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());
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -6,7 +6,7 @@ import ast.ProgramNode;
|
|||||||
import ast.expressions.IExpressionNode;
|
import ast.expressions.IExpressionNode;
|
||||||
import ast.expressions.binaryexpressions.CalculationNode;
|
import ast.expressions.binaryexpressions.CalculationNode;
|
||||||
import ast.expressions.binaryexpressions.DotNode;
|
import ast.expressions.binaryexpressions.DotNode;
|
||||||
import ast.expressions.binaryexpressions.DotSubtractionNode;
|
import ast.expressions.binaryexpressions.DotSubstractionNode;
|
||||||
import ast.expressions.binaryexpressions.NonCalculationNode;
|
import ast.expressions.binaryexpressions.NonCalculationNode;
|
||||||
import ast.expressions.unaryexpressions.MemberAccessNode;
|
import ast.expressions.unaryexpressions.MemberAccessNode;
|
||||||
import ast.expressions.unaryexpressions.UnaryNode;
|
import ast.expressions.unaryexpressions.UnaryNode;
|
||||||
@@ -14,19 +14,23 @@ import ast.members.*;
|
|||||||
import ast.parameters.ParameterNode;
|
import ast.parameters.ParameterNode;
|
||||||
import ast.statementexpressions.AssignNode;
|
import ast.statementexpressions.AssignNode;
|
||||||
import ast.statementexpressions.AssignableNode;
|
import ast.statementexpressions.AssignableNode;
|
||||||
import ast.statementexpressions.NewDeclarationNode;
|
|
||||||
import ast.statementexpressions.crementexpressions.CrementType;
|
import ast.statementexpressions.crementexpressions.CrementType;
|
||||||
import ast.statementexpressions.crementexpressions.DecrementNode;
|
import ast.statementexpressions.crementexpressions.DecrementNode;
|
||||||
import ast.statementexpressions.crementexpressions.IncrementNode;
|
import ast.statementexpressions.crementexpressions.IncrementNode;
|
||||||
|
import ast.statementexpressions.NewDeclarationNode;
|
||||||
import ast.statementexpressions.methodcallstatementnexpressions.MethodCallNode;
|
import ast.statementexpressions.methodcallstatementnexpressions.MethodCallNode;
|
||||||
import ast.statementexpressions.methodcallstatementnexpressions.TargetNode;
|
|
||||||
import ast.statements.*;
|
import ast.statements.*;
|
||||||
|
import ast.statementexpressions.methodcallstatementnexpressions.TargetNode;
|
||||||
|
import ast.statements.BlockNode;
|
||||||
|
import ast.statements.LocalVariableDeclarationNode;
|
||||||
|
import ast.statements.ReturnNode;
|
||||||
import ast.type.AccessModifierNode;
|
import ast.type.AccessModifierNode;
|
||||||
import ast.type.EnumValueNode;
|
import ast.type.EnumValueNode;
|
||||||
import ast.type.ValueNode;
|
import ast.type.ValueNode;
|
||||||
import ast.type.type.BaseType;
|
import ast.type.type.BaseType;
|
||||||
import ast.type.type.ReferenceType;
|
import ast.type.type.ReferenceType;
|
||||||
import ast.type.type.TypeEnum;
|
import ast.type.type.TypeEnum;
|
||||||
|
|
||||||
import org.junit.jupiter.api.DisplayName;
|
import org.junit.jupiter.api.DisplayName;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
@@ -35,99 +39,97 @@ import static org.assertj.core.api.Assertions.assertThat;
|
|||||||
@DisplayName("Untyped Abstract Syntax Tree")
|
@DisplayName("Untyped Abstract Syntax Tree")
|
||||||
class AstBuilderTest {
|
class AstBuilderTest {
|
||||||
|
|
||||||
private final static String directoryPath = "src/test/resources/input/singleFeatureTests/";
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("Empty Class Test")
|
@DisplayName("Empty Class Test")
|
||||||
public void emptyClassTest(){
|
public void emptyClassTest(){
|
||||||
ClassNode emptyClass = Helper.generateEmptyClass("EmptyClass");
|
ClassNode emptyClass = Helper.generateEmptyClass("TestClass");
|
||||||
ProgramNode expected = new ProgramNode();
|
ProgramNode expected = new ProgramNode();
|
||||||
expected.addClass(emptyClass);
|
expected.addClass(emptyClass);
|
||||||
|
|
||||||
ASTNode actual = Helper.generateAST(directoryPath + "EmptyClass.java");
|
ASTNode actual = Helper.generateAST("src/test/resources/input/javaCases/EmptyClass.java");
|
||||||
assertThat(actual).isEqualToComparingFieldByFieldRecursively(expected);
|
assertThat(actual).isEqualToComparingFieldByFieldRecursively(expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("Multiple Empty Classes Test")
|
@DisplayName("Multiple Empty Classes Test")
|
||||||
public void multipleEmptyClassesTest() {
|
public void multipleEmptyClassesTest() {
|
||||||
ClassNode class1 = Helper.generateEmptyClass("MultipleClasses");
|
ClassNode class1 = Helper.generateEmptyClass("TestClass1");
|
||||||
ClassNode class2 = Helper.generateEmptyClass("TestClass2");
|
ClassNode class2 = Helper.generateEmptyClass("TestClass2");
|
||||||
ProgramNode expected = new ProgramNode();
|
ProgramNode expected = new ProgramNode();
|
||||||
expected.addClass(class1);
|
expected.addClass(class1);
|
||||||
expected.addClass(class2);
|
expected.addClass(class2);
|
||||||
|
|
||||||
ASTNode actual = Helper.generateAST(directoryPath + "MultipleClasses.java");
|
ASTNode actual = Helper.generateAST("src/test/resources/input/javaCases/MultipleClasses.java");
|
||||||
assertThat(actual).isEqualToComparingFieldByFieldRecursively(expected);
|
assertThat(actual).isEqualToComparingFieldByFieldRecursively(expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("Empty Class Test with Constructor")
|
@DisplayName("Empty Class Test with Constructor")
|
||||||
public void emptyClassWithConstructorTest() {
|
public void emptyClassWithConstructorTest() {
|
||||||
ClassNode class1 = Helper.generateEmptyClass("EmptyClassWithConstructor");
|
ClassNode class1 = Helper.generateEmptyClass("TestClass");
|
||||||
ProgramNode expected = new ProgramNode();
|
ProgramNode expected = new ProgramNode();
|
||||||
expected.addClass(class1);
|
expected.addClass(class1);
|
||||||
|
|
||||||
ASTNode actual = Helper.generateAST(directoryPath + "EmptyClassWithConstructor.java");
|
ASTNode actual = Helper.generateAST("src/test/resources/input/javaCases/EmptyClassWithConstructor.java");
|
||||||
assertThat(actual).isEqualToComparingFieldByFieldRecursively(expected);
|
assertThat(actual).isEqualToComparingFieldByFieldRecursively(expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("Field Test")
|
@DisplayName("Field Test")
|
||||||
public void fieldTest() {
|
public void fieldTest() {
|
||||||
ClassNode class1 = Helper.generateEmptyClass("Field");
|
ClassNode class1 = Helper.generateEmptyClass("TestClass");
|
||||||
class1.addMember(new FieldNode(new AccessModifierNode("public"), new BaseType(TypeEnum.INT), "a"));
|
class1.addMember(new FieldNode(new AccessModifierNode("public"), new BaseType(TypeEnum.INT), "a"));
|
||||||
|
|
||||||
ProgramNode expected = new ProgramNode();
|
ProgramNode expected = new ProgramNode();
|
||||||
expected.addClass(class1);
|
expected.addClass(class1);
|
||||||
|
|
||||||
ASTNode actual = Helper.generateAST(directoryPath + "Field.java");
|
ASTNode actual = Helper.generateAST("src/test/resources/input/javaCases/Field.java");
|
||||||
assertThat(actual).isEqualToComparingFieldByFieldRecursively(expected);
|
assertThat(actual).isEqualToComparingFieldByFieldRecursively(expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("Field Test with Accessmodifier")
|
@DisplayName("Field Test with Accessmodifier")
|
||||||
public void fieldTestWithModifier() {
|
public void fieldTestWithModifier() {
|
||||||
ClassNode class1 = Helper.generateEmptyClass("FieldWithAccessModifier");
|
ClassNode class1 = Helper.generateEmptyClass("TestClass");
|
||||||
class1.addMember(new FieldNode(new AccessModifierNode("public"), new BaseType(TypeEnum.INT), "a"));
|
class1.addMember(new FieldNode(new AccessModifierNode("public"), new BaseType(TypeEnum.INT), "a"));
|
||||||
|
|
||||||
ProgramNode expected = new ProgramNode();
|
ProgramNode expected = new ProgramNode();
|
||||||
expected.addClass(class1);
|
expected.addClass(class1);
|
||||||
|
|
||||||
ASTNode actual = Helper.generateAST(directoryPath + "FieldWithAccessModifier.java");
|
ASTNode actual = Helper.generateAST("src/test/resources/input/javaCases/FieldWithAccessModifier.java");
|
||||||
assertThat(actual).isEqualToComparingFieldByFieldRecursively(expected);
|
assertThat(actual).isEqualToComparingFieldByFieldRecursively(expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("Comments Ignore Test")
|
@DisplayName("Commments Ignore Test")
|
||||||
public void commentsIgnoreTest() {
|
public void commmentsIgnoreTest(){
|
||||||
ClassNode class1 = Helper.generateEmptyClass("Comments");
|
ClassNode class1 = Helper.generateEmptyClass("TestClass");
|
||||||
class1.addMember(new FieldNode(new AccessModifierNode("private"), new BaseType(TypeEnum.INT), "a"));
|
class1.addMember(new FieldNode(new AccessModifierNode("private"), new BaseType(TypeEnum.INT), "a"));
|
||||||
|
|
||||||
ProgramNode expected = new ProgramNode();
|
ProgramNode expected = new ProgramNode();
|
||||||
expected.addClass(class1);
|
expected.addClass(class1);
|
||||||
|
|
||||||
ASTNode actual = Helper.generateAST(directoryPath + "Comments.java");
|
ASTNode actual = Helper.generateAST("src/test/resources/input/javaCases/Comments.java");
|
||||||
|
|
||||||
assertThat(actual).isEqualToComparingFieldByFieldRecursively(expected);
|
assertThat(actual).isEqualToComparingFieldByFieldRecursively(expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("Constructor Parameter Test")
|
@DisplayName("Constructor Paramerter Test")
|
||||||
public void constructorParameterTest(){
|
public void constructorParameterTest(){
|
||||||
BlockNode block = new BlockNode();
|
BlockNode block = new BlockNode();
|
||||||
block.addStatement(new ReturnNode(null));
|
block.addStatement(new ReturnNode(null));
|
||||||
ConstructorNode constructor = new ConstructorNode("public", "ConstructorParameter", block);
|
ConstructorNode constructor = new ConstructorNode("public", "TestClass", block);
|
||||||
constructor.addParameter(new ParameterNode(new BaseType(TypeEnum.INT), "a"));
|
constructor.addParameter(new ParameterNode(new BaseType(TypeEnum.INT), "a"));
|
||||||
constructor.addParameter(new ParameterNode(new BaseType(TypeEnum.INT), "b"));
|
constructor.addParameter(new ParameterNode(new BaseType(TypeEnum.INT), "b"));
|
||||||
|
|
||||||
ClassNode class1 = new ClassNode("public", "ConstructorParameter");
|
ClassNode class1 = new ClassNode("public", "TestClass");
|
||||||
class1.addMember(constructor);
|
class1.addMember(constructor);
|
||||||
|
|
||||||
ProgramNode expected = new ProgramNode();
|
ProgramNode expected = new ProgramNode();
|
||||||
expected.addClass(class1);
|
expected.addClass(class1);
|
||||||
|
|
||||||
ASTNode actual = Helper.generateAST(directoryPath + "ConstructorParameter.java");
|
ASTNode actual = Helper.generateAST("src/test/resources/input/javaCases/ConstructorParameter.java");
|
||||||
|
|
||||||
assertThat(actual).isEqualToComparingFieldByFieldRecursively(expected);
|
assertThat(actual).isEqualToComparingFieldByFieldRecursively(expected);
|
||||||
}
|
}
|
||||||
@@ -146,16 +148,16 @@ class AstBuilderTest {
|
|||||||
|
|
||||||
block.addStatement(new AssignNode(assignable, expression));
|
block.addStatement(new AssignNode(assignable, expression));
|
||||||
block.addStatement(new ReturnNode(null));
|
block.addStatement(new ReturnNode(null));
|
||||||
ConstructorNode constructor = new ConstructorNode("public", "ThisDot", block);
|
ConstructorNode constructor = new ConstructorNode("public", "TestClass", block);
|
||||||
|
|
||||||
ClassNode class1 = new ClassNode("public", "ThisDot");
|
ClassNode class1 = new ClassNode("public", "TestClass");
|
||||||
class1.addMember(new FieldNode(new AccessModifierNode("public"), new BaseType(TypeEnum.INT), "a"));
|
class1.addMember(new FieldNode(new AccessModifierNode("public"), new BaseType(TypeEnum.INT), "a"));
|
||||||
class1.addMember(constructor);
|
class1.addMember(constructor);
|
||||||
|
|
||||||
ProgramNode expected = new ProgramNode();
|
ProgramNode expected = new ProgramNode();
|
||||||
expected.addClass(class1);
|
expected.addClass(class1);
|
||||||
|
|
||||||
ASTNode actual = Helper.generateAST(directoryPath + "ThisDot.java");
|
ASTNode actual = Helper.generateAST("src/test/resources/input/javaCases/ThisDot.java");
|
||||||
|
|
||||||
assertThat(actual).isEqualToComparingFieldByFieldRecursively(expected);
|
assertThat(actual).isEqualToComparingFieldByFieldRecursively(expected);
|
||||||
}
|
}
|
||||||
@@ -173,17 +175,17 @@ class AstBuilderTest {
|
|||||||
|
|
||||||
block.addStatement(new AssignNode(assignable, expression));
|
block.addStatement(new AssignNode(assignable, expression));
|
||||||
block.addStatement(new ReturnNode(null));
|
block.addStatement(new ReturnNode(null));
|
||||||
ConstructorNode constructor = new ConstructorNode("public", "ConstructorThisDot", block);
|
ConstructorNode constructor = new ConstructorNode("public", "TestClass", block);
|
||||||
constructor.addParameter(new ParameterNode(new BaseType(TypeEnum.INT), "a"));
|
constructor.addParameter(new ParameterNode(new BaseType(TypeEnum.INT), "a"));
|
||||||
|
|
||||||
ClassNode class1 = new ClassNode("public", "ConstructorThisDot");
|
ClassNode class1 = new ClassNode("public", "TestClass");
|
||||||
class1.addMember(new FieldNode(new AccessModifierNode("private"), new BaseType(TypeEnum.INT), "a"));
|
class1.addMember(new FieldNode(new AccessModifierNode("private"), new BaseType(TypeEnum.INT), "a"));
|
||||||
class1.addMember(constructor);
|
class1.addMember(constructor);
|
||||||
|
|
||||||
ProgramNode expected = new ProgramNode();
|
ProgramNode expected = new ProgramNode();
|
||||||
expected.addClass(class1);
|
expected.addClass(class1);
|
||||||
|
|
||||||
ASTNode actual = Helper.generateAST(directoryPath + "ConstructorThisDot.java");
|
ASTNode actual = Helper.generateAST("src/test/resources/input/javaCases/ConstructorThisDot.java");
|
||||||
|
|
||||||
assertThat(actual).isEqualToComparingFieldByFieldRecursively(expected);
|
assertThat(actual).isEqualToComparingFieldByFieldRecursively(expected);
|
||||||
}
|
}
|
||||||
@@ -191,7 +193,7 @@ class AstBuilderTest {
|
|||||||
@Test
|
@Test
|
||||||
@DisplayName("Void Methoden Test")
|
@DisplayName("Void Methoden Test")
|
||||||
public void voidMethodenTest(){
|
public void voidMethodenTest(){
|
||||||
ClassNode class1 = Helper.generateEmptyClass("VoidMethod");
|
ClassNode class1 = Helper.generateEmptyClass("TestClass");
|
||||||
BlockNode block = new BlockNode();
|
BlockNode block = new BlockNode();
|
||||||
block.addStatement(new ReturnNode(null));
|
block.addStatement(new ReturnNode(null));
|
||||||
class1.addMember(new MethodNode("public", null, true, "test", block));
|
class1.addMember(new MethodNode("public", null, true, "test", block));
|
||||||
@@ -199,7 +201,7 @@ class AstBuilderTest {
|
|||||||
ProgramNode expected = new ProgramNode();
|
ProgramNode expected = new ProgramNode();
|
||||||
expected.addClass(class1);
|
expected.addClass(class1);
|
||||||
|
|
||||||
ASTNode actual = Helper.generateAST(directoryPath + "VoidMethod.java");
|
ASTNode actual = Helper.generateAST("src/test/resources/input/javaCases/VoidMethod.java");
|
||||||
|
|
||||||
assertThat(actual).isEqualToComparingFieldByFieldRecursively(expected);
|
assertThat(actual).isEqualToComparingFieldByFieldRecursively(expected);
|
||||||
}
|
}
|
||||||
@@ -217,13 +219,13 @@ class AstBuilderTest {
|
|||||||
|
|
||||||
blockCon.addStatement(new AssignNode(assignable, expression));
|
blockCon.addStatement(new AssignNode(assignable, expression));
|
||||||
blockCon.addStatement(new ReturnNode(null));
|
blockCon.addStatement(new ReturnNode(null));
|
||||||
ConstructorNode constructor = new ConstructorNode("public", "ConstructorMethodCall", blockCon);
|
ConstructorNode constructor = new ConstructorNode("public", "TestClass", blockCon);
|
||||||
|
|
||||||
BlockNode blockMethod = new BlockNode();
|
BlockNode blockMethod = new BlockNode();
|
||||||
blockMethod.addStatement(new ReturnNode(new UnaryNode(new ValueNode(EnumValueNode.INT_VALUE, "1"))));
|
blockMethod.addStatement(new ReturnNode(new UnaryNode(new ValueNode(EnumValueNode.INT_VALUE, "1"))));
|
||||||
MethodNode method = new MethodNode("public", new BaseType(TypeEnum.INT), false, "testMethod", blockMethod);
|
MethodNode method = new MethodNode("public", new BaseType(TypeEnum.INT), false, "testMethod", blockMethod);
|
||||||
|
|
||||||
ClassNode class1 = new ClassNode("public", "ConstructorMethodCall");
|
ClassNode class1 = new ClassNode("public", "TestClass");
|
||||||
class1.addMember(new FieldNode(new AccessModifierNode("public"), new BaseType(TypeEnum.INT), "a"));
|
class1.addMember(new FieldNode(new AccessModifierNode("public"), new BaseType(TypeEnum.INT), "a"));
|
||||||
class1.addMember(constructor);
|
class1.addMember(constructor);
|
||||||
class1.addMember(method);
|
class1.addMember(method);
|
||||||
@@ -231,7 +233,7 @@ class AstBuilderTest {
|
|||||||
ProgramNode expected = new ProgramNode();
|
ProgramNode expected = new ProgramNode();
|
||||||
expected.addClass(class1);
|
expected.addClass(class1);
|
||||||
|
|
||||||
ASTNode actual = Helper.generateAST(directoryPath + "ConstructorMethodCall.java");
|
ASTNode actual = Helper.generateAST("src/test/resources/input/javaCases/ConstructorMethodCall.java");
|
||||||
|
|
||||||
assertThat(actual).isEqualToComparingFieldByFieldRecursively(expected);
|
assertThat(actual).isEqualToComparingFieldByFieldRecursively(expected);
|
||||||
}
|
}
|
||||||
@@ -251,7 +253,7 @@ class AstBuilderTest {
|
|||||||
|
|
||||||
blockCon.addStatement(new AssignNode(assignable, expression));
|
blockCon.addStatement(new AssignNode(assignable, expression));
|
||||||
blockCon.addStatement(new ReturnNode(null));
|
blockCon.addStatement(new ReturnNode(null));
|
||||||
ConstructorNode constructor = new ConstructorNode("public", "ConstructorMethodCallParameters", blockCon);
|
ConstructorNode constructor = new ConstructorNode("public", "TestClass", blockCon);
|
||||||
constructor.addParameter(new ParameterNode(new BaseType(TypeEnum.INT), "a"));
|
constructor.addParameter(new ParameterNode(new BaseType(TypeEnum.INT), "a"));
|
||||||
|
|
||||||
BlockNode blockMethod = new BlockNode();
|
BlockNode blockMethod = new BlockNode();
|
||||||
@@ -259,7 +261,7 @@ class AstBuilderTest {
|
|||||||
MethodNode method = new MethodNode("public", new BaseType(TypeEnum.INT), false, "testMethod", blockMethod);
|
MethodNode method = new MethodNode("public", new BaseType(TypeEnum.INT), false, "testMethod", blockMethod);
|
||||||
method.addParameter(new ParameterNode(new BaseType(TypeEnum.INT), "a"));
|
method.addParameter(new ParameterNode(new BaseType(TypeEnum.INT), "a"));
|
||||||
|
|
||||||
ClassNode class1 = new ClassNode("public", "ConstructorMethodCallParameters");
|
ClassNode class1 = new ClassNode("public", "TestClass");
|
||||||
class1.addMember(new FieldNode(new AccessModifierNode("public"), new BaseType(TypeEnum.INT), "a"));
|
class1.addMember(new FieldNode(new AccessModifierNode("public"), new BaseType(TypeEnum.INT), "a"));
|
||||||
class1.addMember(constructor);
|
class1.addMember(constructor);
|
||||||
class1.addMember(method);
|
class1.addMember(method);
|
||||||
@@ -267,7 +269,7 @@ class AstBuilderTest {
|
|||||||
ProgramNode expected = new ProgramNode();
|
ProgramNode expected = new ProgramNode();
|
||||||
expected.addClass(class1);
|
expected.addClass(class1);
|
||||||
|
|
||||||
ASTNode actual = Helper.generateAST(directoryPath + "ConstructorMethodCallParameters.java");
|
ASTNode actual = Helper.generateAST("src/test/resources/input/javaCases/ConstructorMethodCallParameters.java");
|
||||||
|
|
||||||
assertThat(actual).isEqualToComparingFieldByFieldRecursively(expected);
|
assertThat(actual).isEqualToComparingFieldByFieldRecursively(expected);
|
||||||
}
|
}
|
||||||
@@ -287,7 +289,7 @@ class AstBuilderTest {
|
|||||||
|
|
||||||
blockCon.addStatement(new AssignNode(assignable, expression));
|
blockCon.addStatement(new AssignNode(assignable, expression));
|
||||||
blockCon.addStatement(new ReturnNode(null));
|
blockCon.addStatement(new ReturnNode(null));
|
||||||
ConstructorNode constructor = new ConstructorNode("public", "Char", blockCon);
|
ConstructorNode constructor = new ConstructorNode("public", "TestClass", blockCon);
|
||||||
constructor.addParameter(new ParameterNode(new BaseType(TypeEnum.CHAR), "a"));
|
constructor.addParameter(new ParameterNode(new BaseType(TypeEnum.CHAR), "a"));
|
||||||
|
|
||||||
BlockNode blockMethod = new BlockNode();
|
BlockNode blockMethod = new BlockNode();
|
||||||
@@ -295,7 +297,7 @@ class AstBuilderTest {
|
|||||||
MethodNode method = new MethodNode("public", new BaseType(TypeEnum.CHAR), false, "testMethod", blockMethod);
|
MethodNode method = new MethodNode("public", new BaseType(TypeEnum.CHAR), false, "testMethod", blockMethod);
|
||||||
method.addParameter(new ParameterNode(new BaseType(TypeEnum.CHAR), "a"));
|
method.addParameter(new ParameterNode(new BaseType(TypeEnum.CHAR), "a"));
|
||||||
|
|
||||||
ClassNode class1 = new ClassNode("public", "Char");
|
ClassNode class1 = new ClassNode("public", "TestClass");
|
||||||
class1.addMember(new FieldNode(new AccessModifierNode("public"), new BaseType(TypeEnum.CHAR), "a"));
|
class1.addMember(new FieldNode(new AccessModifierNode("public"), new BaseType(TypeEnum.CHAR), "a"));
|
||||||
class1.addMember(constructor);
|
class1.addMember(constructor);
|
||||||
class1.addMember(method);
|
class1.addMember(method);
|
||||||
@@ -303,7 +305,7 @@ class AstBuilderTest {
|
|||||||
ProgramNode expected = new ProgramNode();
|
ProgramNode expected = new ProgramNode();
|
||||||
expected.addClass(class1);
|
expected.addClass(class1);
|
||||||
|
|
||||||
ASTNode actual = Helper.generateAST(directoryPath + "Char.java");
|
ASTNode actual = Helper.generateAST("src/test/resources/input/javaCases/Char.java");
|
||||||
|
|
||||||
assertThat(actual).isEqualToComparingFieldByFieldRecursively(expected);
|
assertThat(actual).isEqualToComparingFieldByFieldRecursively(expected);
|
||||||
}
|
}
|
||||||
@@ -319,102 +321,16 @@ class AstBuilderTest {
|
|||||||
|
|
||||||
blockCon.addStatement(new AssignNode(assignable, new UnaryNode(new ValueNode(EnumValueNode.NULL_VALUE, "null"))));
|
blockCon.addStatement(new AssignNode(assignable, new UnaryNode(new ValueNode(EnumValueNode.NULL_VALUE, "null"))));
|
||||||
blockCon.addStatement(new ReturnNode(null));
|
blockCon.addStatement(new ReturnNode(null));
|
||||||
ConstructorNode constructor = new ConstructorNode("public", "Null", blockCon);
|
ConstructorNode constructor = new ConstructorNode("public", "TestClass", blockCon);
|
||||||
|
|
||||||
ClassNode class1 = new ClassNode("public", "Null");
|
ClassNode class1 = new ClassNode("public", "TestClass");
|
||||||
class1.addMember(new FieldNode(new AccessModifierNode("public"), new ReferenceType("Null"), "a"));
|
class1.addMember(new FieldNode(new AccessModifierNode("public"), new BaseType(TypeEnum.INT), "a"));
|
||||||
class1.addMember(constructor);
|
class1.addMember(constructor);
|
||||||
|
|
||||||
ProgramNode expected = new ProgramNode();
|
ProgramNode expected = new ProgramNode();
|
||||||
expected.addClass(class1);
|
expected.addClass(class1);
|
||||||
|
|
||||||
ASTNode actual = Helper.generateAST(directoryPath + "Null.java");
|
ASTNode actual = Helper.generateAST("src/test/resources/input/javaCases/Null.java");
|
||||||
|
|
||||||
assertThat(actual).isEqualToComparingFieldByFieldRecursively(expected);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
@DisplayName("If Test")
|
|
||||||
public void ifTest() {
|
|
||||||
BlockNode block = new BlockNode();
|
|
||||||
block.addStatement(new LocalVariableDeclarationNode(new BaseType(TypeEnum.INT), "intValue", "=", new UnaryNode(new ValueNode(EnumValueNode.INT_VALUE, "5"))));
|
|
||||||
|
|
||||||
BlockNode ifBlock = new BlockNode();
|
|
||||||
ifBlock.addStatement(new DecrementNode(CrementType.SUFFIX, new AssignableNode("intValue")));
|
|
||||||
block.addStatement(new IfElseNode(new IfNode(new NonCalculationNode(new UnaryNode("intValue"), "==", new UnaryNode(new ValueNode(EnumValueNode.INT_VALUE, "5"))), ifBlock), null));
|
|
||||||
|
|
||||||
block.addStatement(new ReturnNode(null));
|
|
||||||
|
|
||||||
ConstructorNode constructor = new ConstructorNode("public", "If", block);
|
|
||||||
|
|
||||||
ClassNode class1 = new ClassNode("public", "If");
|
|
||||||
class1.addMember(constructor);
|
|
||||||
|
|
||||||
ProgramNode expected = new ProgramNode();
|
|
||||||
expected.addClass(class1);
|
|
||||||
|
|
||||||
ASTNode actual = Helper.generateAST(directoryPath + "If.java");
|
|
||||||
|
|
||||||
assertThat(actual).isEqualToComparingFieldByFieldRecursively(expected);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
@DisplayName("If Else Test")
|
|
||||||
public void ifElseTest() {
|
|
||||||
BlockNode block = new BlockNode();
|
|
||||||
block.addStatement(new LocalVariableDeclarationNode(new BaseType(TypeEnum.INT), "intValue", "=", new UnaryNode(new ValueNode(EnumValueNode.INT_VALUE, "5"))));
|
|
||||||
|
|
||||||
BlockNode ifBlock = new BlockNode();
|
|
||||||
ifBlock.addStatement(new DecrementNode(CrementType.SUFFIX, new AssignableNode("intValue")));
|
|
||||||
BlockNode elseBlock = new BlockNode();
|
|
||||||
elseBlock.addStatement(new IncrementNode(CrementType.SUFFIX, new AssignableNode("intValue")));
|
|
||||||
block.addStatement(new IfElseNode(new IfNode(new NonCalculationNode(new UnaryNode("intValue"), "==", new UnaryNode(new ValueNode(EnumValueNode.INT_VALUE, "5"))), ifBlock), new ElseNode(elseBlock)));
|
|
||||||
|
|
||||||
block.addStatement(new ReturnNode(null));
|
|
||||||
|
|
||||||
ConstructorNode constructor = new ConstructorNode("public", "IfElse", block);
|
|
||||||
|
|
||||||
ClassNode class1 = new ClassNode("public", "IfElse");
|
|
||||||
class1.addMember(constructor);
|
|
||||||
|
|
||||||
ProgramNode expected = new ProgramNode();
|
|
||||||
expected.addClass(class1);
|
|
||||||
|
|
||||||
ASTNode actual = Helper.generateAST(directoryPath + "IfElse.java");
|
|
||||||
|
|
||||||
assertThat(actual).isEqualToComparingFieldByFieldRecursively(expected);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
@DisplayName("If Else If ElseTest")
|
|
||||||
public void ifElseIfElseTest() {
|
|
||||||
BlockNode block = new BlockNode();
|
|
||||||
block.addStatement(new LocalVariableDeclarationNode(new BaseType(TypeEnum.INT), "intValue", "=", new UnaryNode(new ValueNode(EnumValueNode.INT_VALUE, "5"))));
|
|
||||||
|
|
||||||
BlockNode ifBlock = new BlockNode();
|
|
||||||
ifBlock.addStatement(new DecrementNode(CrementType.SUFFIX, new AssignableNode("intValue")));
|
|
||||||
BlockNode elseBlock = new BlockNode();
|
|
||||||
elseBlock.addStatement(new IncrementNode(CrementType.SUFFIX, new AssignableNode("intValue")));
|
|
||||||
|
|
||||||
IfElseNode ifElseStatement = new IfElseNode(new IfNode(new NonCalculationNode(new UnaryNode("intValue"), "==", new UnaryNode(new ValueNode(EnumValueNode.INT_VALUE, "5"))), ifBlock), new ElseNode(elseBlock));
|
|
||||||
|
|
||||||
BlockNode ifElseBlock = new BlockNode();
|
|
||||||
ifElseBlock.addStatement(new IncrementNode(CrementType.SUFFIX, new AssignableNode("intValue")));
|
|
||||||
ifElseStatement.addElseIfStatement(new IfNode(new NonCalculationNode(new UnaryNode("intValue"), "==", new UnaryNode(new ValueNode(EnumValueNode.INT_VALUE, "4"))), ifElseBlock));
|
|
||||||
|
|
||||||
block.addStatement(ifElseStatement);
|
|
||||||
|
|
||||||
block.addStatement(new ReturnNode(null));
|
|
||||||
|
|
||||||
ConstructorNode constructor = new ConstructorNode("public", "IfElseIfElse", block);
|
|
||||||
|
|
||||||
ClassNode class1 = new ClassNode("public", "IfElseIfElse");
|
|
||||||
class1.addMember(constructor);
|
|
||||||
|
|
||||||
ProgramNode expected = new ProgramNode();
|
|
||||||
expected.addClass(class1);
|
|
||||||
|
|
||||||
ASTNode actual = Helper.generateAST(directoryPath + "IfElseIfElse.java");
|
|
||||||
|
|
||||||
assertThat(actual).isEqualToComparingFieldByFieldRecursively(expected);
|
assertThat(actual).isEqualToComparingFieldByFieldRecursively(expected);
|
||||||
}
|
}
|
||||||
@@ -423,9 +339,9 @@ class AstBuilderTest {
|
|||||||
@DisplayName("Self Reference Test")
|
@DisplayName("Self Reference Test")
|
||||||
public void selfReferneceTest(){
|
public void selfReferneceTest(){
|
||||||
|
|
||||||
ClassNode testClass = Helper.generateEmptyClass("SelfReference");
|
ClassNode testClass = Helper.generateEmptyClass("TestClass");
|
||||||
|
|
||||||
MemberNode testClassObject = new FieldNode(new AccessModifierNode("public"), new ReferenceType("SelfReference"),"selfReference");
|
MemberNode testClassObject = new FieldNode(new AccessModifierNode("public"), new ReferenceType("TestClass"),"testClass");
|
||||||
|
|
||||||
BlockNode testMethod1Block = new BlockNode();
|
BlockNode testMethod1Block = new BlockNode();
|
||||||
testMethod1Block.addStatement(new ReturnNode(new UnaryNode(new MethodCallNode(new TargetNode(true), "testMethod2"))));
|
testMethod1Block.addStatement(new ReturnNode(new UnaryNode(new MethodCallNode(new TargetNode(true), "testMethod2"))));
|
||||||
@@ -436,10 +352,10 @@ class AstBuilderTest {
|
|||||||
MethodNode testMethod2 = new MethodNode("public", new BaseType(TypeEnum.INT), false, "testMethod2", testMethod2Block);
|
MethodNode testMethod2 = new MethodNode("public", new BaseType(TypeEnum.INT), false, "testMethod2", testMethod2Block);
|
||||||
|
|
||||||
BlockNode testMethod3Block = new BlockNode();
|
BlockNode testMethod3Block = new BlockNode();
|
||||||
testMethod3Block.addStatement(new LocalVariableDeclarationNode(new ReferenceType("SelfReference"),"selfReference1", "=", new UnaryNode(new NewDeclarationNode("SelfReference")))); // Assing einfach "=" ?
|
testMethod3Block.addStatement(new LocalVariableDeclarationNode(new ReferenceType("TestClass"),"testClass1", "=", new UnaryNode(new NewDeclarationNode("TestClass")))); // Assing einfach "=" ?
|
||||||
MemberAccessNode methodAccess = new MemberAccessNode(false);
|
MemberAccessNode methodAccess = new MemberAccessNode(false);
|
||||||
methodAccess.addIdentifier("selfReference1");
|
methodAccess.addIdentifier("testClass1");
|
||||||
methodAccess.addIdentifier("selfReference");
|
methodAccess.addIdentifier("testClass");
|
||||||
TargetNode methodTarget = new TargetNode(methodAccess);
|
TargetNode methodTarget = new TargetNode(methodAccess);
|
||||||
testMethod3Block.addStatement(new ReturnNode(new UnaryNode(new MethodCallNode(methodTarget,"testMethod1"))));
|
testMethod3Block.addStatement(new ReturnNode(new UnaryNode(new MethodCallNode(methodTarget,"testMethod1"))));
|
||||||
MethodNode testMethod3 = new MethodNode("public", new BaseType(TypeEnum.INT), false, "testMethod3", testMethod3Block);
|
MethodNode testMethod3 = new MethodNode("public", new BaseType(TypeEnum.INT), false, "testMethod3", testMethod3Block);
|
||||||
@@ -452,7 +368,7 @@ class AstBuilderTest {
|
|||||||
ProgramNode expected = new ProgramNode();
|
ProgramNode expected = new ProgramNode();
|
||||||
expected.addClass(testClass);
|
expected.addClass(testClass);
|
||||||
|
|
||||||
ASTNode actual = Helper.generateAST(directoryPath + "SelfReference.java");
|
ASTNode actual = Helper.generateAST("src/test/resources/input/javaCases/SelfReference.java");
|
||||||
|
|
||||||
assertThat(actual).isEqualToComparingFieldByFieldRecursively(expected);
|
assertThat(actual).isEqualToComparingFieldByFieldRecursively(expected);
|
||||||
}
|
}
|
||||||
@@ -460,7 +376,7 @@ class AstBuilderTest {
|
|||||||
@Test
|
@Test
|
||||||
@DisplayName("Variable Compare Test")
|
@DisplayName("Variable Compare Test")
|
||||||
public void variableCompareTest(){
|
public void variableCompareTest(){
|
||||||
ClassNode class1 = Helper.generateEmptyClass("VariableCompare");
|
ClassNode class1 = Helper.generateEmptyClass("TestClass");
|
||||||
UnaryNode trueValue = new UnaryNode(new ValueNode(EnumValueNode.BOOLEAN_VALUE,"true"));
|
UnaryNode trueValue = new UnaryNode(new ValueNode(EnumValueNode.BOOLEAN_VALUE,"true"));
|
||||||
UnaryNode falseValue = new UnaryNode(new ValueNode(EnumValueNode.BOOLEAN_VALUE,"false"));
|
UnaryNode falseValue = new UnaryNode(new ValueNode(EnumValueNode.BOOLEAN_VALUE,"false"));
|
||||||
|
|
||||||
@@ -503,7 +419,7 @@ class AstBuilderTest {
|
|||||||
ProgramNode expected = new ProgramNode();
|
ProgramNode expected = new ProgramNode();
|
||||||
expected.addClass(class1);
|
expected.addClass(class1);
|
||||||
|
|
||||||
ASTNode actual = Helper.generateAST(directoryPath + "VariableCompare.java");
|
ASTNode actual = Helper.generateAST("src/test/resources/input/javaCases/variableCompare.java");
|
||||||
|
|
||||||
assertThat(actual).isEqualToComparingFieldByFieldRecursively(expected);
|
assertThat(actual).isEqualToComparingFieldByFieldRecursively(expected);
|
||||||
}
|
}
|
||||||
@@ -511,34 +427,34 @@ class AstBuilderTest {
|
|||||||
@Test
|
@Test
|
||||||
@DisplayName("Variable Calculation Test")
|
@DisplayName("Variable Calculation Test")
|
||||||
public void variableCalculationTest(){
|
public void variableCalculationTest(){
|
||||||
ClassNode class1 = Helper.generateEmptyClass("VariableCalculation");
|
ClassNode class1 = Helper.generateEmptyClass("TestClass");
|
||||||
|
|
||||||
BlockNode aPlusBBlock = new BlockNode();
|
BlockNode aPlusBBlock = new BlockNode();
|
||||||
aPlusBBlock.addStatement(new ReturnNode(new CalculationNode(new CalculationNode(new DotNode(new DotSubtractionNode("a"))), "+", new DotNode(new DotSubtractionNode("b")))));
|
aPlusBBlock.addStatement(new ReturnNode(new CalculationNode(new CalculationNode(new DotNode(new DotSubstractionNode("a"))), "+", new DotNode(new DotSubstractionNode("b")))));
|
||||||
MethodNode aPlusBMethod = new MethodNode("public", new BaseType(TypeEnum.INT), false, "aPlusB", aPlusBBlock);
|
MethodNode aPlusBMethod = new MethodNode("public", new BaseType(TypeEnum.INT), false, "aPlusB", aPlusBBlock);
|
||||||
aPlusBMethod.addParameter(new ParameterNode(new BaseType(TypeEnum.INT), "a"));
|
aPlusBMethod.addParameter(new ParameterNode(new BaseType(TypeEnum.INT), "a"));
|
||||||
aPlusBMethod.addParameter(new ParameterNode(new BaseType(TypeEnum.INT), "b"));
|
aPlusBMethod.addParameter(new ParameterNode(new BaseType(TypeEnum.INT), "b"));
|
||||||
|
|
||||||
BlockNode aMinusBBlock = new BlockNode();
|
BlockNode aMinusBBlock = new BlockNode();
|
||||||
aMinusBBlock.addStatement(new ReturnNode(new CalculationNode(new CalculationNode(new DotNode(new DotSubtractionNode("a"))), "-", new DotNode(new DotSubtractionNode("b")))));
|
aMinusBBlock.addStatement(new ReturnNode(new CalculationNode(new CalculationNode(new DotNode(new DotSubstractionNode("a"))), "-", new DotNode(new DotSubstractionNode("b")))));
|
||||||
MethodNode aMinusBMethod = new MethodNode("public", new BaseType(TypeEnum.INT), false, "aMinusB", aMinusBBlock);
|
MethodNode aMinusBMethod = new MethodNode("public", new BaseType(TypeEnum.INT), false, "aMinusB", aMinusBBlock);
|
||||||
aMinusBMethod.addParameter(new ParameterNode(new BaseType(TypeEnum.INT), "a"));
|
aMinusBMethod.addParameter(new ParameterNode(new BaseType(TypeEnum.INT), "a"));
|
||||||
aMinusBMethod.addParameter(new ParameterNode(new BaseType(TypeEnum.INT), "b"));
|
aMinusBMethod.addParameter(new ParameterNode(new BaseType(TypeEnum.INT), "b"));
|
||||||
|
|
||||||
BlockNode aTimeBBlock = new BlockNode();
|
BlockNode aTimeBBlock = new BlockNode();
|
||||||
aTimeBBlock.addStatement(new ReturnNode(new CalculationNode(new DotNode(new DotNode(new DotSubtractionNode("a")), "*", new DotSubtractionNode("b")))));
|
aTimeBBlock.addStatement(new ReturnNode(new CalculationNode(new DotNode(new DotNode(new DotSubstractionNode("a")), "*", new DotSubstractionNode("b")))));
|
||||||
MethodNode aTimeBMethod = new MethodNode("public", new BaseType(TypeEnum.INT), false, "aTimeB", aTimeBBlock);
|
MethodNode aTimeBMethod = new MethodNode("public", new BaseType(TypeEnum.INT), false, "aTimeB", aTimeBBlock);
|
||||||
aTimeBMethod.addParameter(new ParameterNode(new BaseType(TypeEnum.INT), "a"));
|
aTimeBMethod.addParameter(new ParameterNode(new BaseType(TypeEnum.INT), "a"));
|
||||||
aTimeBMethod.addParameter(new ParameterNode(new BaseType(TypeEnum.INT), "b"));
|
aTimeBMethod.addParameter(new ParameterNode(new BaseType(TypeEnum.INT), "b"));
|
||||||
|
|
||||||
BlockNode aDivBBlock = new BlockNode();
|
BlockNode aDivBBlock = new BlockNode();
|
||||||
aDivBBlock.addStatement(new ReturnNode(new CalculationNode(new DotNode(new DotNode(new DotSubtractionNode("a")), "/", new DotSubtractionNode("b")))));
|
aDivBBlock.addStatement(new ReturnNode(new CalculationNode(new DotNode(new DotNode(new DotSubstractionNode("a")), "/", new DotSubstractionNode("b")))));
|
||||||
MethodNode aDivBMethod = new MethodNode("public", new BaseType(TypeEnum.INT), false, "aDivB", aDivBBlock);
|
MethodNode aDivBMethod = new MethodNode("public", new BaseType(TypeEnum.INT), false, "aDivB", aDivBBlock);
|
||||||
aDivBMethod.addParameter(new ParameterNode(new BaseType(TypeEnum.INT), "a"));
|
aDivBMethod.addParameter(new ParameterNode(new BaseType(TypeEnum.INT), "a"));
|
||||||
aDivBMethod.addParameter(new ParameterNode(new BaseType(TypeEnum.INT), "b"));
|
aDivBMethod.addParameter(new ParameterNode(new BaseType(TypeEnum.INT), "b"));
|
||||||
|
|
||||||
BlockNode complexCalcBlock = new BlockNode();
|
BlockNode complexCalcBlock = new BlockNode();
|
||||||
complexCalcBlock.addStatement(new ReturnNode(new CalculationNode(null, null, new DotNode(new DotNode(new DotNode(new DotNode(new DotSubtractionNode("a")), "*", new DotSubtractionNode("b")), "/", new DotSubtractionNode(new ValueNode(EnumValueNode.INT_VALUE, "1"))), "*", new DotSubtractionNode(new ValueNode(EnumValueNode.INT_VALUE, "3"))))));
|
complexCalcBlock.addStatement(new ReturnNode(new CalculationNode(null, null, new DotNode(new DotNode(new DotNode(new DotNode(new DotSubstractionNode("a")), "*", new DotSubstractionNode("b")), "/", new DotSubstractionNode(new ValueNode(EnumValueNode.INT_VALUE, "1"))), "*", new DotSubstractionNode(new ValueNode(EnumValueNode.INT_VALUE, "3"))))));
|
||||||
MethodNode complexCalcMethod = new MethodNode("public", new BaseType(TypeEnum.INT), false, "complexCalc", complexCalcBlock);
|
MethodNode complexCalcMethod = new MethodNode("public", new BaseType(TypeEnum.INT), false, "complexCalc", complexCalcBlock);
|
||||||
complexCalcMethod.addParameter(new ParameterNode(new BaseType(TypeEnum.INT), "a"));
|
complexCalcMethod.addParameter(new ParameterNode(new BaseType(TypeEnum.INT), "a"));
|
||||||
complexCalcMethod.addParameter(new ParameterNode(new BaseType(TypeEnum.INT), "b"));
|
complexCalcMethod.addParameter(new ParameterNode(new BaseType(TypeEnum.INT), "b"));
|
||||||
@@ -573,7 +489,7 @@ class AstBuilderTest {
|
|||||||
ProgramNode expected = new ProgramNode();
|
ProgramNode expected = new ProgramNode();
|
||||||
expected.addClass(class1);
|
expected.addClass(class1);
|
||||||
|
|
||||||
ASTNode actual = Helper.generateAST(directoryPath + "VariableCalculation.java");
|
ASTNode actual = Helper.generateAST("src/test/resources/input/javaCases/variableCalculation.java");
|
||||||
|
|
||||||
assertThat(actual).isEqualToComparingFieldByFieldRecursively(expected);
|
assertThat(actual).isEqualToComparingFieldByFieldRecursively(expected);
|
||||||
}
|
}
|
||||||
@@ -581,7 +497,7 @@ class AstBuilderTest {
|
|||||||
@Test
|
@Test
|
||||||
@DisplayName("Main Method Test")
|
@DisplayName("Main Method Test")
|
||||||
public void mainMethodTest(){
|
public void mainMethodTest(){
|
||||||
ClassNode class1 = Helper.generateEmptyClass("MainMethod");
|
ClassNode class1 = Helper.generateEmptyClass("TestClass");
|
||||||
|
|
||||||
BlockNode block = new BlockNode();
|
BlockNode block = new BlockNode();
|
||||||
block.addStatement(new ReturnNode(null));
|
block.addStatement(new ReturnNode(null));
|
||||||
@@ -591,7 +507,7 @@ class AstBuilderTest {
|
|||||||
ProgramNode expected = new ProgramNode();
|
ProgramNode expected = new ProgramNode();
|
||||||
expected.addClass(class1);
|
expected.addClass(class1);
|
||||||
|
|
||||||
ASTNode actual = Helper.generateAST(directoryPath + "MainMethod.java");
|
ASTNode actual = Helper.generateAST("src/test/resources/input/javaCases/MainMethod.java");
|
||||||
|
|
||||||
assertThat(actual).isEqualToComparingFieldByFieldRecursively(expected);
|
assertThat(actual).isEqualToComparingFieldByFieldRecursively(expected);
|
||||||
}
|
}
|
||||||
@@ -612,13 +528,13 @@ class AstBuilderTest {
|
|||||||
blockCon.addStatement(new ReturnNode(null));
|
blockCon.addStatement(new ReturnNode(null));
|
||||||
ConstructorNode constructor = new ConstructorNode("public", "TestClass", blockCon);
|
ConstructorNode constructor = new ConstructorNode("public", "TestClass", blockCon);
|
||||||
|
|
||||||
ClassNode class1 = new ClassNode("public", "While");
|
ClassNode class1 = new ClassNode("public", "TestClass");
|
||||||
class1.addMember(constructor);
|
class1.addMember(constructor);
|
||||||
|
|
||||||
ProgramNode expected = new ProgramNode();
|
ProgramNode expected = new ProgramNode();
|
||||||
expected.addClass(class1);
|
expected.addClass(class1);
|
||||||
|
|
||||||
ASTNode actual = Helper.generateAST(directoryPath + "While.java");
|
ASTNode actual = Helper.generateAST("src/test/resources/input/javaCases/While.java");
|
||||||
|
|
||||||
assertThat(actual).isEqualToComparingFieldByFieldRecursively(expected);
|
assertThat(actual).isEqualToComparingFieldByFieldRecursively(expected);
|
||||||
}
|
}
|
||||||
@@ -643,13 +559,13 @@ class AstBuilderTest {
|
|||||||
blockCon.addStatement(new ReturnNode(null));
|
blockCon.addStatement(new ReturnNode(null));
|
||||||
ConstructorNode constructor = new ConstructorNode("public", "TestClass", blockCon);
|
ConstructorNode constructor = new ConstructorNode("public", "TestClass", blockCon);
|
||||||
|
|
||||||
ClassNode class1 = new ClassNode("public", "DoWhile");
|
ClassNode class1 = new ClassNode("public", "TestClass");
|
||||||
class1.addMember(constructor);
|
class1.addMember(constructor);
|
||||||
|
|
||||||
ProgramNode expected = new ProgramNode();
|
ProgramNode expected = new ProgramNode();
|
||||||
expected.addClass(class1);
|
expected.addClass(class1);
|
||||||
|
|
||||||
ASTNode actual = Helper.generateAST(directoryPath + "DoWhile.java");
|
ASTNode actual = Helper.generateAST("src/test/resources/input/javaCases/DoWhile.java");
|
||||||
|
|
||||||
assertThat(actual).isEqualToComparingFieldByFieldRecursively(expected);
|
assertThat(actual).isEqualToComparingFieldByFieldRecursively(expected);
|
||||||
}
|
}
|
||||||
@@ -679,13 +595,13 @@ class AstBuilderTest {
|
|||||||
blockCon.addStatement(new ReturnNode(null));
|
blockCon.addStatement(new ReturnNode(null));
|
||||||
ConstructorNode constructor = new ConstructorNode("public", "TestClass", blockCon);
|
ConstructorNode constructor = new ConstructorNode("public", "TestClass", blockCon);
|
||||||
|
|
||||||
ClassNode class1 = new ClassNode("public", "For");
|
ClassNode class1 = new ClassNode("public", "TestClass");
|
||||||
class1.addMember(constructor);
|
class1.addMember(constructor);
|
||||||
|
|
||||||
ProgramNode expected = new ProgramNode();
|
ProgramNode expected = new ProgramNode();
|
||||||
expected.addClass(class1);
|
expected.addClass(class1);
|
||||||
|
|
||||||
ASTNode actual = Helper.generateAST(directoryPath + "For.java");
|
ASTNode actual = Helper.generateAST("src/test/resources/input/javaCases/For.java");
|
||||||
|
|
||||||
assertThat(actual).isEqualToComparingFieldByFieldRecursively(expected);
|
assertThat(actual).isEqualToComparingFieldByFieldRecursively(expected);
|
||||||
}
|
}
|
||||||
|
@@ -2,10 +2,12 @@ package parser;
|
|||||||
|
|
||||||
import ast.ASTNode;
|
import ast.ASTNode;
|
||||||
import ast.ClassNode;
|
import ast.ClassNode;
|
||||||
|
import ast.ProgramNode;
|
||||||
import ast.members.ConstructorNode;
|
import ast.members.ConstructorNode;
|
||||||
import ast.members.MemberNode;
|
import ast.members.MemberNode;
|
||||||
import ast.statements.BlockNode;
|
import ast.statements.BlockNode;
|
||||||
import ast.statements.ReturnNode;
|
import ast.statements.ReturnNode;
|
||||||
|
import ast.type.AccessModifierNode;
|
||||||
import org.antlr.v4.runtime.CharStream;
|
import org.antlr.v4.runtime.CharStream;
|
||||||
import org.antlr.v4.runtime.CharStreams;
|
import org.antlr.v4.runtime.CharStreams;
|
||||||
import org.antlr.v4.runtime.CommonTokenStream;
|
import org.antlr.v4.runtime.CommonTokenStream;
|
||||||
|
138
src/test/java/parser/ParserTest.java
Normal file
138
src/test/java/parser/ParserTest.java
Normal file
@@ -0,0 +1,138 @@
|
|||||||
|
package parser;
|
||||||
|
|
||||||
|
import org.antlr.v4.runtime.*;
|
||||||
|
import org.antlr.v4.runtime.tree.ParseTree;
|
||||||
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import parser.generated.SimpleJavaLexer;
|
||||||
|
import parser.generated.SimpleJavaParser;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
public class ParserTest {
|
||||||
|
/*
|
||||||
|
@BeforeEach
|
||||||
|
public void init() { // noch nicht benötigt
|
||||||
|
String inputFilePath = "src/main/resources/input/CompilerInput.java";
|
||||||
|
String outputDirectoryPath = "src/main/resources/output";
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void parserTest() {
|
||||||
|
// init
|
||||||
|
CharStream inputCharStream = CharStreams.fromString("public class Name {}");
|
||||||
|
SimpleJavaLexer lexer = new SimpleJavaLexer(inputCharStream);
|
||||||
|
CommonTokenStream tokenStream = new CommonTokenStream(lexer);
|
||||||
|
tokenStream.fill();
|
||||||
|
|
||||||
|
|
||||||
|
/* Parser -> Parsetree */
|
||||||
|
SimpleJavaParser parser = new SimpleJavaParser(tokenStream);
|
||||||
|
ParseTree parseTree = parser.program(); // parse the input
|
||||||
|
|
||||||
|
//Variante 1 (geht)
|
||||||
|
String expectedParseTreeAsString = "(program (classDeclaration public class Name { }))";
|
||||||
|
String actualParseTreeAsString = parseTree.toStringTree(parser);
|
||||||
|
|
||||||
|
assertEquals(expectedParseTreeAsString, actualParseTreeAsString);
|
||||||
|
|
||||||
|
// Variante 2 (geht nicht)
|
||||||
|
// - Sollte es gehen und es liegt am Parser? (keine Ahnung) -> Bitte Fehler (actual und expected) durchlesen
|
||||||
|
// ist die Methode parseStringToTree() korrekt? -> (glaub nicht)
|
||||||
|
Map<String, Object> expectedTreeStructure = parseStringToTree(expectedParseTreeAsString);
|
||||||
|
Map<String, Object> actualTreeStructure = buildTreeStructure(parseTree, parser);
|
||||||
|
|
||||||
|
// assertEquals(expectedTreeStructure, actualTreeStructure);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Helpers Variante 2.1
|
||||||
|
|
||||||
|
public static Map<String, Object> buildTreeStructure(ParseTree tree, Parser parser) {
|
||||||
|
return buildTree(tree, parser, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Map<String, Object> buildTree(ParseTree tree, Parser parser, int indent) {
|
||||||
|
Map<String, Object> node = new HashMap<>();
|
||||||
|
|
||||||
|
if (tree instanceof RuleContext) {
|
||||||
|
int ruleIndex = ((RuleContext) tree).getRuleIndex();
|
||||||
|
String ruleName = parser.getRuleNames()[ruleIndex];
|
||||||
|
node.put("rule", ruleName);
|
||||||
|
} else {
|
||||||
|
node.put("text", tree.getText());
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Map<String, Object>> children = new ArrayList<>();
|
||||||
|
for (int i = 0; i < tree.getChildCount(); i++) {
|
||||||
|
children.add(buildTree(tree.getChild(i), parser, indent + 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!children.isEmpty()) {
|
||||||
|
node.put("children", children);
|
||||||
|
}
|
||||||
|
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Helpers Variante 2.2
|
||||||
|
|
||||||
|
public static Map<String, Object> parseStringToTree(String input) {
|
||||||
|
input = input.trim();
|
||||||
|
if (input.startsWith("(") && input.endsWith(")")) {
|
||||||
|
input = input.substring(1, input.length() - 1).trim();
|
||||||
|
}
|
||||||
|
return parse(input);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Map<String, Object> parse(String input) {
|
||||||
|
Map<String, Object> node = new HashMap<>();
|
||||||
|
StringBuilder currentToken = new StringBuilder();
|
||||||
|
List<Map<String, Object>> children = new ArrayList<>();
|
||||||
|
|
||||||
|
int depth = 0;
|
||||||
|
boolean inToken = false;
|
||||||
|
for (char ch : input.toCharArray()) {
|
||||||
|
if (ch == '(') {
|
||||||
|
if (depth == 0) {
|
||||||
|
if (!currentToken.isEmpty()) {
|
||||||
|
node.put("node", currentToken.toString().trim());
|
||||||
|
currentToken.setLength(0);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
currentToken.append(ch);
|
||||||
|
}
|
||||||
|
depth++;
|
||||||
|
} else if (ch == ')') {
|
||||||
|
depth--;
|
||||||
|
if (depth == 0) {
|
||||||
|
children.add(parse(currentToken.toString().trim()));
|
||||||
|
currentToken.setLength(0);
|
||||||
|
} else {
|
||||||
|
currentToken.append(ch);
|
||||||
|
}
|
||||||
|
} else if (Character.isWhitespace(ch) && depth == 0) {
|
||||||
|
if (!currentToken.isEmpty()) {
|
||||||
|
node.put("node", currentToken.toString().trim());
|
||||||
|
currentToken.setLength(0);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
currentToken.append(ch);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!currentToken.isEmpty()) {
|
||||||
|
node.put("node", currentToken.toString().trim());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!children.isEmpty()) {
|
||||||
|
node.put("children", children);
|
||||||
|
}
|
||||||
|
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
}
|
45
src/test/java/parser/ScannerTest.java
Normal file
45
src/test/java/parser/ScannerTest.java
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
package parser;
|
||||||
|
|
||||||
|
import org.antlr.v4.runtime.CharStream;
|
||||||
|
import org.antlr.v4.runtime.CharStreams;
|
||||||
|
import org.antlr.v4.runtime.CommonTokenStream;
|
||||||
|
import org.antlr.v4.runtime.Token;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import parser.generated.SimpleJavaLexer;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
|
||||||
|
public class ScannerTest {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This test method is used to test the scanner functionality of the SimpleJavaLexer.
|
||||||
|
* It creates a CharStream from a string representing a simple Java class declaration,
|
||||||
|
* and uses the SimpleJavaLexer to tokenize this input.
|
||||||
|
* It then compares the actual tokens and their types produced by the lexer to the expected tokens and their types.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void scannerTest() {
|
||||||
|
// Create a CharStream from a string representing a simple Java class declaration
|
||||||
|
CharStream inputCharStream = CharStreams.fromString("public class Name {}");
|
||||||
|
|
||||||
|
// Use the SimpleJavaLexer to tokenize the input
|
||||||
|
SimpleJavaLexer lexer = new SimpleJavaLexer(inputCharStream);
|
||||||
|
CommonTokenStream tokenStream = new CommonTokenStream(lexer);
|
||||||
|
tokenStream.fill();
|
||||||
|
|
||||||
|
// Prepare the expected results
|
||||||
|
List<String> expectedTokens = Arrays.asList("public", "class", "Name", "{", "}", "<EOF>");
|
||||||
|
List<String> expectedTokenTypes = Arrays.asList("AccessModifier", "Class", "Identifier", "OpenCurlyBracket", "ClosedCurlyBracket", "EOF");
|
||||||
|
List<Token> actualTokens = tokenStream.getTokens();
|
||||||
|
|
||||||
|
// Compare the actual tokens and their types to the expected tokens and their types
|
||||||
|
assertEquals(expectedTokens.size(), actualTokens.size());
|
||||||
|
for (int i = 0; i < expectedTokens.size(); i++) {
|
||||||
|
assertEquals(expectedTokens.get(i), actualTokens.get(i).getText());
|
||||||
|
assertEquals(expectedTokenTypes.get(i), SimpleJavaLexer.VOCABULARY.getSymbolicName(actualTokens.get(i).getType()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
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());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -26,8 +26,6 @@ import java.util.regex.Matcher;
|
|||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import semantic.exceptions.*;
|
|
||||||
import semantic.exceptions.NotDeclaredException;
|
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.*;
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
|
|
||||||
@@ -40,14 +38,17 @@ public class EndToTypedAstTest {
|
|||||||
|
|
||||||
CharStream codeCharStream = null;
|
CharStream codeCharStream = null;
|
||||||
try {
|
try {
|
||||||
codeCharStream = CharStreams.fromPath(Paths.get("src/test/resources/input/typedAstFeatureTests/CorrectTest.java"));
|
codeCharStream = CharStreams.fromPath(Paths.get("src/test/resources/input/typedAstFeaturesTests/CorrectTest.java"));
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
SimpleJavaLexer lexer = new SimpleJavaLexer(codeCharStream);
|
SimpleJavaLexer lexer = new SimpleJavaLexer(codeCharStream);
|
||||||
CommonTokenStream tokenStream = new CommonTokenStream(lexer);
|
CommonTokenStream tokenStream = new CommonTokenStream(lexer);
|
||||||
|
|
||||||
SimpleJavaParser parser = new SimpleJavaParser(tokenStream);
|
SimpleJavaParser parser = new SimpleJavaParser(tokenStream);
|
||||||
ParseTree parseTree = parser.program();
|
ParseTree parseTree = parser.program(); // parse the input
|
||||||
|
|
||||||
|
/* ------------------------- AST builder -> AST ------------------------- */
|
||||||
ASTBuilder astBuilder = new ASTBuilder();
|
ASTBuilder astBuilder = new ASTBuilder();
|
||||||
ProgramNode abstractSyntaxTree = (ProgramNode) astBuilder.visit(parseTree);
|
ProgramNode abstractSyntaxTree = (ProgramNode) astBuilder.visit(parseTree);
|
||||||
|
|
||||||
@@ -114,7 +115,7 @@ public class EndToTypedAstTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void featureTest() {
|
public void featureTest() {
|
||||||
String directoryPath = "src/test/resources/input/typedAstFeatureTests";
|
String directoryPath = "src/test/resources/input/typedAstFeaturesTests";
|
||||||
File folder = new File(directoryPath);
|
File folder = new File(directoryPath);
|
||||||
if (folder.isDirectory()) {
|
if (folder.isDirectory()) {
|
||||||
File[] files = folder.listFiles((_, name) -> name.endsWith(".java"));
|
File[] files = folder.listFiles((_, name) -> name.endsWith(".java"));
|
||||||
@@ -154,200 +155,6 @@ public class EndToTypedAstTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
@Test
|
|
||||||
public void notDeclared() {
|
|
||||||
ASTNode tast = SemanticHelper.generateTypedASTFrom("src/test/resources/input/johnsTests/NotDeclared.java");
|
|
||||||
|
|
||||||
SemanticAnalyzer.generateTast(tast);
|
|
||||||
|
|
||||||
assertFalse(SemanticAnalyzer.errors.isEmpty());
|
|
||||||
assertTrue(SemanticAnalyzer.errors.stream().anyMatch(c -> c instanceof NotDeclaredException));
|
|
||||||
}*/
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void typeMismatchTest() {
|
|
||||||
ASTNode tast = SemanticHelper.generateTypedASTFrom("src/test/resources/input/singleFeatureSemanticTests/TypeMismatchIntBool.java");
|
|
||||||
|
|
||||||
SemanticAnalyzer.generateTast(tast);
|
|
||||||
|
|
||||||
assertFalse(SemanticAnalyzer.errors.isEmpty());
|
|
||||||
assertTrue(SemanticAnalyzer.errors.stream().anyMatch(c -> c instanceof TypeMismatchException));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void parameterAlreadyDecleared() {
|
|
||||||
ASTNode tast = SemanticHelper.generateTypedASTFrom("src/test/resources/input/singleFeatureSemanticTests/ParameterAlreadyDecleared.java");
|
|
||||||
|
|
||||||
SemanticAnalyzer.generateTast(tast);
|
|
||||||
|
|
||||||
assertFalse(SemanticAnalyzer.errors.isEmpty());
|
|
||||||
assertTrue(SemanticAnalyzer.errors.stream().anyMatch(c -> c instanceof AlreadyDeclaredException));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void fieldAlreadyDecleared(){
|
|
||||||
ASTNode tast = SemanticHelper.generateTypedASTFrom("src/test/resources/input/singleFeatureSemanticTests/FieldAlreadyDecleared.java");
|
|
||||||
SemanticAnalyzer.generateTast(tast);
|
|
||||||
|
|
||||||
assertFalse(SemanticAnalyzer.errors.isEmpty());
|
|
||||||
assertTrue(SemanticAnalyzer.errors.stream().anyMatch(c -> c instanceof AlreadyDeclaredException));
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void typeMismatchRefType(){
|
|
||||||
ASTNode tast = SemanticHelper.generateTypedASTFrom("src/test/resources/input/singleFeatureSemanticTests/TypeMismatchRefType.java");
|
|
||||||
|
|
||||||
SemanticAnalyzer.generateTast(tast);
|
|
||||||
|
|
||||||
assertFalse(SemanticAnalyzer.errors.isEmpty());
|
|
||||||
assertTrue(SemanticAnalyzer.errors.stream().anyMatch(c -> c instanceof TypeMismatchException));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void correctRetType(){
|
|
||||||
ASTNode tast = SemanticHelper.generateTypedASTFrom("src/test/resources/input/singleFeatureSemanticTests/CorrectRetType.java");
|
|
||||||
|
|
||||||
SemanticAnalyzer.generateTast(tast);
|
|
||||||
|
|
||||||
assertTrue(SemanticAnalyzer.errors.isEmpty());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void retTypeMismatch(){
|
|
||||||
ASTNode tast = SemanticHelper.generateTypedASTFrom("src/test/resources/input/singleFeatureSemanticTests/RetTypeMismatch.java");
|
|
||||||
|
|
||||||
SemanticAnalyzer.generateTast(tast);
|
|
||||||
|
|
||||||
assertFalse(SemanticAnalyzer.errors.isEmpty());
|
|
||||||
assertTrue(SemanticAnalyzer.errors.stream().anyMatch(c -> c instanceof TypeMismatchException));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void multipleRetType(){
|
|
||||||
ASTNode tast = SemanticHelper.generateTypedASTFrom("src/test/resources/input/singleFeatureSemanticTests/MultipleRetTypes.java");
|
|
||||||
|
|
||||||
SemanticAnalyzer.generateTast(tast);
|
|
||||||
|
|
||||||
assertFalse(SemanticAnalyzer.errors.isEmpty());
|
|
||||||
assertTrue(SemanticAnalyzer.errors.stream().anyMatch(c -> c instanceof MultipleReturnTypes));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void BothTypesMustBeSameGreaterSmallerEqual(){
|
|
||||||
|
|
||||||
ASTNode tast = SemanticHelper.generateTypedASTFrom("src/test/resources/input/singleFeatureSemanticTests/BothTypesMustBeSame.java");
|
|
||||||
|
|
||||||
SemanticAnalyzer.generateTast(tast);
|
|
||||||
|
|
||||||
assertFalse(SemanticAnalyzer.errors.isEmpty());
|
|
||||||
assertTrue(SemanticAnalyzer.errors.stream().anyMatch(c -> c instanceof TypeMismatchException));
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void NoSuchType(){
|
|
||||||
|
|
||||||
ASTNode tast = SemanticHelper.generateTypedASTFrom("src/test/resources/input/singleFeatureSemanticTests/ClassNotDeclared.java");
|
|
||||||
|
|
||||||
SemanticAnalyzer.generateTast(tast);
|
|
||||||
|
|
||||||
assertFalse(SemanticAnalyzer.errors.isEmpty());
|
|
||||||
assertTrue(SemanticAnalyzer.errors.stream().anyMatch(c -> c instanceof NotDeclaredException));
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void FieldIsNotVisible(){
|
|
||||||
|
|
||||||
ASTNode tast = SemanticHelper.generateTypedASTFrom("src/test/resources/input/singleFeatureSemanticTests/FieldIsNotVisible.java");
|
|
||||||
|
|
||||||
SemanticAnalyzer.generateTast(tast);
|
|
||||||
|
|
||||||
assertFalse(SemanticAnalyzer.errors.isEmpty());
|
|
||||||
assertTrue(SemanticAnalyzer.errors.stream().anyMatch(c -> c instanceof NotVisibleException));
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void ChainedMethods(){
|
|
||||||
|
|
||||||
ASTNode tast = SemanticHelper.generateTypedASTFrom("src/test/resources/input/singleFeatureSemanticTests/ChainedMethods.java");
|
|
||||||
|
|
||||||
SemanticAnalyzer.generateTast(tast);
|
|
||||||
|
|
||||||
assertTrue(SemanticAnalyzer.errors.isEmpty());
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@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 ------------------
|
||||||
|
|
||||||
|
@@ -1,35 +0,0 @@
|
|||||||
package semantic;
|
|
||||||
|
|
||||||
import ast.ASTNode;
|
|
||||||
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 parser.astBuilder.ASTBuilder;
|
|
||||||
import parser.generated.SimpleJavaLexer;
|
|
||||||
import parser.generated.SimpleJavaParser;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
public class SemanticHelper {
|
|
||||||
public static ASTNode generateTypedASTFrom(String filePath) {
|
|
||||||
|
|
||||||
SemanticAnalyzer.clearAnalyzer();
|
|
||||||
|
|
||||||
CharStream testFile = null;
|
|
||||||
try {
|
|
||||||
testFile = CharStreams.fromFileName(filePath);
|
|
||||||
} catch (IOException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
SimpleJavaLexer lexer = new SimpleJavaLexer(testFile);
|
|
||||||
CommonTokenStream tokenStream = new CommonTokenStream(lexer);
|
|
||||||
tokenStream.fill();
|
|
||||||
SimpleJavaParser parser = new SimpleJavaParser(tokenStream);
|
|
||||||
ParseTree parseTree = parser.program();
|
|
||||||
ASTBuilder astBuilder = new ASTBuilder();
|
|
||||||
|
|
||||||
return astBuilder.visit(parseTree);
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,441 +1,113 @@
|
|||||||
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
|
public void 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
|
public void test(int a, boolean b){
|
||||||
@DisplayName("Variable Compare Test")
|
|
||||||
public void variableCompareTest() {
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
public void test(boolean b, int a){
|
||||||
@DisplayName("Variable Calculation Test")
|
|
||||||
public void variableCalculationTest() {
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
// @Test
|
||||||
@DisplayName("Main Method Test")
|
// public void alreadyDeclaredLocalFieldVar() {
|
||||||
public void mainMethodTest() {
|
// ProgramNode programNode = new ProgramNode();
|
||||||
|
// List<ClassNode> classList = new ArrayList<>();
|
||||||
}
|
// AccessTypeNode accessTypeNode = new AccessTypeNode(EnumAccessTypeNode.PUBLIC);
|
||||||
|
// ClassNode classNode = new ClassNode(accessTypeNode, "testClass");
|
||||||
@Test
|
//
|
||||||
@DisplayName("While Test")
|
// SemanticAnalyzer semanticAnalyzer = new SemanticAnalyzer();
|
||||||
public void whileTest() {
|
// ASTNode tast = semanticAnalyzer.generateTast(ast);
|
||||||
|
//
|
||||||
}
|
// MemberNode memberNode2 = new FieldNode(accessTypeNode, new BaseTypeNode(EnumTypeNode.INT), "testVar");
|
||||||
|
// classNode.members.add(memberNode2);
|
||||||
@Test
|
//
|
||||||
@DisplayName("Do While Test")
|
// classList.add(classNode);
|
||||||
public void doWhileTest() {
|
// programNode.classes = classList;
|
||||||
|
//
|
||||||
}
|
// ASTNode typedAst = SemanticAnalyzer.generateTast(programNode);
|
||||||
|
//
|
||||||
@Test
|
// assertEquals(1, SemanticAnalyzer.errors.size());
|
||||||
@DisplayName("For Test")
|
// assertInstanceOf(AlreadyDeclaredException.class, SemanticAnalyzer.errors.getFirst());
|
||||||
public void forTest() {
|
// assertNull(typedAst);
|
||||||
|
// }
|
||||||
}
|
//
|
||||||
|
// @Test
|
||||||
@Test
|
// public void shouldWorkWithNoError() {
|
||||||
@DisplayName("Increment Test")
|
// ProgramNode programNode = new ProgramNode();
|
||||||
public void incrementTest() {
|
// List<ClassNode> classList = new ArrayList<>();
|
||||||
ClassNode classNode = Helper.generateEmptyClass("Increment");
|
// AccessTypeNode accessTypeNode = new AccessTypeNode(EnumAccessTypeNode.PUBLIC);
|
||||||
classNode.addMember(new FieldNode(new AccessModifierNode("public"), new BaseType(TypeEnum.INT), "a"));
|
// ClassNode classNode = new ClassNode(accessTypeNode, "testClass");
|
||||||
|
//
|
||||||
ProgramNode abstractSyntaxTree = new ProgramNode();
|
// SemanticAnalyzer semanticAnalyzer = new SemanticAnalyzer();
|
||||||
abstractSyntaxTree.addClass(classNode);
|
// ASTNode tast = semanticAnalyzer.generateTast(ast);
|
||||||
|
//
|
||||||
ASTNode typedAst = SemanticAnalyzer.generateTast(abstractSyntaxTree);
|
// assertEquals(semanticAnalyzer.errors.size(), 0);
|
||||||
for (Exception runtimeException : SemanticAnalyzer.errors) {
|
// assertNotNull(tast);
|
||||||
runtimeException.printStackTrace();
|
//
|
||||||
}
|
// MemberNode memberNode3 = getMemberNode(accessTypeNode);
|
||||||
assertTrue(SemanticAnalyzer.errors.isEmpty());
|
// classNode.members.add(memberNode3);
|
||||||
assertNotNull(typedAst);
|
//
|
||||||
}
|
// classList.add(classNode);
|
||||||
|
// programNode.classes = classList;
|
||||||
|
//
|
||||||
|
// ASTNode typedAst = SemanticAnalyzer.generateTast(programNode);
|
||||||
|
//
|
||||||
|
// assertEquals(0, SemanticAnalyzer.errors.size());
|
||||||
|
// assertEquals(programNode, typedAst);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// /**
|
||||||
|
// * This method is used to create a MemberNode representing a method.
|
||||||
|
// * It first creates a list of ParameterNodes and adds a ParameterNode to it.
|
||||||
|
// * Then, it creates a ParameterListNode using the list of ParameterNodes.
|
||||||
|
// * After that, it creates a list of StatementNodes and adds a StatementNode to it by calling the getStatementNode method.
|
||||||
|
// * Finally, it creates a MethodNode using the provided AccessTypeNode, a BaseTypeNode representing the return type of the method,
|
||||||
|
// * the method name, the ParameterListNode, and the list of StatementNodes, and returns this MethodNode.
|
||||||
|
// *
|
||||||
|
// * @param accessTypeNode The AccessTypeNode representing the access type of the method.
|
||||||
|
// * @return The created MemberNode representing the method.
|
||||||
|
// */
|
||||||
|
//private static MemberNode getMemberNode(AccessTypeNode accessTypeNode) {
|
||||||
|
// List<ParameterNode> parameterNodeList = new ArrayList<>();
|
||||||
|
// ParameterNode parameterNode1 = new ParameterNode(new BaseTypeNode(EnumTypeNode.INT), "param1");
|
||||||
|
// parameterNodeList.add(parameterNode1);
|
||||||
|
// ParameterListNode parameterListNode = new ParameterListNode(parameterNodeList);
|
||||||
|
//
|
||||||
|
// List<StatementNode> statementNodeList = new ArrayList<>();
|
||||||
|
//
|
||||||
|
// StatementNode statementNode1 = getStatementNode();
|
||||||
|
// statementNodeList.add(statementNode1);
|
||||||
|
//
|
||||||
|
// return new MethodNode(accessTypeNode, new BaseTypeNode(EnumTypeNode.INT), "testVar2", parameterListNode, statementNodeList);
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
// /**
|
||||||
|
// * This method is used to create a StatementNode for an assignment operation.
|
||||||
|
// * It first creates two IdentifierExpressionNodes for 'this' and 'objectVar'.
|
||||||
|
// * Then, it creates a BinaryExpressionNode to represent the operation 'this.objectVar'.
|
||||||
|
// * After that, it creates a LiteralNode to represent the integer value 1.
|
||||||
|
// * Finally, it creates another BinaryExpressionNode to represent the assignment operation 'this.objectVar = 1',
|
||||||
|
// * and wraps this expression in an AssignmentStatementNode.
|
||||||
|
// *
|
||||||
|
// * @return The created AssignmentStatementNode representing the assignment operation 'this.objectVar = 1'.
|
||||||
|
// */
|
||||||
|
//private static StatementNode getStatementNode() {
|
||||||
|
// ExpressionNode expressionNodeObjectVariableLeft = new IdentifierExpressionNode("this");
|
||||||
|
// ExpressionNode expressionNodeObjectVariableRight = new IdentifierExpressionNode("objectVar");
|
||||||
|
//
|
||||||
|
// ExpressionNode expressionNodeLeft = new BinaryExpressionNode(expressionNodeObjectVariableLeft, expressionNodeObjectVariableRight, ExpresssionOperator.DOT);
|
||||||
|
//
|
||||||
|
// ExpressionNode expressionNodeRight = new LiteralNode(1);
|
||||||
|
//
|
||||||
|
// BinaryExpressionNode expressionNode = new BinaryExpressionNode(expressionNodeLeft, expressionNodeRight, ExpresssionOperator.ASSIGNMENT);
|
||||||
|
//
|
||||||
|
// return new AssignmentStatementNode(expressionNode);
|
||||||
|
//}
|
||||||
}
|
}
|
@@ -4,7 +4,7 @@ public class AllFeaturesClassExample {
|
|||||||
char c;
|
char c;
|
||||||
|
|
||||||
// Konstruktor
|
// Konstruktor
|
||||||
public AllFeaturesClassExample(int a, boolean b, char c) {
|
AllFeaturesClassExample(int a, boolean b, char c) {
|
||||||
this.a = a;
|
this.a = a;
|
||||||
this.b = b;
|
this.b = b;
|
||||||
this.c = c;
|
this.c = c;
|
||||||
@@ -14,54 +14,47 @@ public class AllFeaturesClassExample {
|
|||||||
void controlStructures() {
|
void controlStructures() {
|
||||||
// if-else Anweisung
|
// if-else Anweisung
|
||||||
if (a > 10) {
|
if (a > 10) {
|
||||||
|
// System.out.println("a ist größer als 10");
|
||||||
} else {
|
} else {
|
||||||
|
// System.out.println("a ist nicht größer als 10");
|
||||||
}
|
}
|
||||||
|
|
||||||
// while Schleife
|
// while Schleife
|
||||||
while (a > 0) {
|
while (a > 0) {
|
||||||
|
// System.out.println("a ist " + a);
|
||||||
a--;
|
a--;
|
||||||
}
|
}
|
||||||
int c = 0;
|
|
||||||
// for Schleife
|
// for Schleife
|
||||||
for (int i = 0; i < 5; i++) {
|
for (int i = 0; i < 5; i++) {
|
||||||
c++;
|
// System.out.println("for Schleife Iteration: " + i);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Methode zur Arbeit mit logischen Operatoren
|
// Methode zur Arbeit mit logischen Operatoren
|
||||||
void logicalOperations() {
|
void logicalOperations() {
|
||||||
// Logische UND-Operation
|
// Logische UND-Operation
|
||||||
if (b && a > 5) {
|
if (b && a > 5) {
|
||||||
|
// System.out.println("a ist größer als 5 und b ist wahr");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Logische ODER-Operation
|
// Logische ODER-Operation
|
||||||
if (b || a < 5) {
|
if (b || a < 5) {
|
||||||
|
// System.out.println("b ist wahr oder a ist kleiner als 5");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int add(int a, int b) {
|
void mathOperations() {
|
||||||
return a + b;
|
// Addition
|
||||||
}
|
int sum = a + 5;
|
||||||
|
// Subtraktion
|
||||||
int subtract(int a, int b) {
|
int difference = a - 5;
|
||||||
return a - b;
|
// Multiplikation
|
||||||
}
|
int product = a * 5;
|
||||||
|
// Division
|
||||||
int multiply(int a, int b) {
|
int quotient = a / 5;
|
||||||
return a * b;
|
// Modulo
|
||||||
}
|
int remainder = a % 5;
|
||||||
|
|
||||||
int divide(int a, int b) {
|
|
||||||
return a / b;
|
|
||||||
}
|
|
||||||
|
|
||||||
int modulo(int a, int b) {
|
|
||||||
return a % b;
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean greaterThan(int a, int b) {
|
|
||||||
return a > b;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
23
src/test/resources/input/CombinedExample.java
Normal file
23
src/test/resources/input/CombinedExample.java
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
public class CombinedExample {
|
||||||
|
int number;
|
||||||
|
boolean flag;
|
||||||
|
char letter;
|
||||||
|
|
||||||
|
public CombinedExample(int number, boolean flag, char letter) {
|
||||||
|
this.number = number;
|
||||||
|
this.flag = flag;
|
||||||
|
this.letter = letter;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void displayValues() {
|
||||||
|
System.out.println("Number: " + number);
|
||||||
|
System.out.println("Flag: " + flag);
|
||||||
|
System.out.println("Letter: " + letter);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
CombinedExample obj = new CombinedExample(10, true, 'X');
|
||||||
|
obj.displayValues();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
16
src/test/resources/input/CompilerInput.java
Normal file
16
src/test/resources/input/CompilerInput.java
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
public class CompilerInput {
|
||||||
|
|
||||||
|
public int a;
|
||||||
|
|
||||||
|
public static int testMethod(char x){
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public class Test {
|
||||||
|
|
||||||
|
public static int testMethod(char x, int a){
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
6
src/test/resources/input/MoreFeaturesClassExample.java
Normal file
6
src/test/resources/input/MoreFeaturesClassExample.java
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
public class MoreFeaturesClassExample {
|
||||||
|
int hallo;
|
||||||
|
private class Inner {
|
||||||
|
int hallo2;
|
||||||
|
}
|
||||||
|
}
|
@@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
BIN
src/test/resources/input/featureTests/BooleanOperations.class
Normal file
BIN
src/test/resources/input/featureTests/BooleanOperations.class
Normal file
Binary file not shown.
BIN
src/test/resources/input/featureTests/CharManipulation.class
Normal file
BIN
src/test/resources/input/featureTests/CharManipulation.class
Normal file
Binary file not shown.
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user