johns-branch #9

Merged
i22005 merged 13 commits from johns-branch into main 2024-05-30 17:11:51 +00:00
41 changed files with 597 additions and 77 deletions

15
.gitea/workflows/test.yml Normal file
View File

@ -0,0 +1,15 @@
name: Gitea Actions Demo
run-name: ${{ gitea.actor }} is testing out Gitea Actions 🚀
on: [push]
jobs:
Explore-Gitea-Actions:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-java@v4
with:
java-version: '17'
distribution: 'temurin'
- name: Run the Maven verify phase
run: mvn --batch-mode --update-snapshots verify

2
.idea/misc.xml generated
View File

@ -40,7 +40,7 @@
</list> </list>
</option> </option>
</component> </component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_21" default="true" project-jdk-name="openjdk-21" project-jdk-type="JavaSDK"> <component name="ProjectRootManager" version="2" languageLevel="JDK_22" default="true" project-jdk-name="openjdk-22" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/out" /> <output url="file://$PROJECT_DIR$/out" />
</component> </component>
</project> </project>

View File

@ -1,18 +1,21 @@
import ast.ASTNode; import ast.ASTNode;
import ast.ClassNode; import org.antlr.v4.runtime.*;
import org.antlr.v4.runtime.Token;
import ast.ProgramNode; import ast.ProgramNode;
import bytecode.ByteCodeGenerator; import bytecode.ByteCodeGenerator;
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.tree.ParseTree; import org.antlr.v4.runtime.tree.ParseTree;
import org.antlr.v4.runtime.CommonTokenStream;
import parser.ASTBuilder; import parser.ASTBuilder;
import parser.generated.SimpleJavaLexer; import parser.generated.SimpleJavaLexer;
import parser.generated.SimpleJavaParser; import parser.generated.SimpleJavaParser;
import semantic.SemanticAnalyzer; import semantic.SemanticAnalyzer;
import bytecode.ByteCodeGenerator;
import java.io.IOException; import java.io.IOException;
import java.nio.file.Paths; import java.nio.file.Paths;
import java.util.List;
public class Main { public class Main {
public static void main(String[] args) throws Exception { public static void main(String[] args) throws Exception {
@ -30,20 +33,103 @@ public class Main {
static void parseFile(CharStream codeCharStream) { static void parseFile(CharStream codeCharStream) {
/* ------------------------- Scanner -> tokens ------------------------- */
SimpleJavaLexer lexer = new SimpleJavaLexer(codeCharStream); SimpleJavaLexer lexer = new SimpleJavaLexer(codeCharStream);
CommonTokenStream tokens = new CommonTokenStream(lexer); CommonTokenStream tokenStream = new CommonTokenStream(lexer);
SimpleJavaParser parser = new SimpleJavaParser(tokens);
ParseTree tree = parser.program(); // parse the input // Printing the tokens
// tokenStream.fill();
// List<Token> tokens = tokenStream.getTokens();
// System.out.println("-------------------- Scanner -> tokens --------------------");
// for (Token token : tokens) {
// String tokenType = SimpleJavaLexer.VOCABULARY.getSymbolicName(token.getType());
// String tokenText = token.getText();
// // System.out.println("Token Type: " + tokenType + ", Token Text: " +
// // tokenText);
// System.out.println(tokenType + " " + tokenText);
// }
// System.out.println();
ASTBuilder builder = new ASTBuilder(); /* ------------------------- Parser -> Parsetree ------------------------- */
ProgramNode ast = (ProgramNode) builder.visit(tree); // build the AST SimpleJavaParser parser = new SimpleJavaParser(tokenStream);
ParseTree parseTree = parser.program(); // parse the input
ProgramNode typedAst = (ProgramNode) SemanticAnalyzer.generateTast(ast); // Printing the parse tree
// System.out.println("-------------------- Parser -> Parsetree --------------------");
// System.out.println(parseTree.toStringTree(parser));
// printTree(parseTree, parser, 0);
// System.out.println();
/* ------------------------- AST builder -> AST ------------------------- */
ASTBuilder astBuilder = new ASTBuilder();
ProgramNode abstractSyntaxTree = (ProgramNode) astBuilder.visit(parseTree);
// Printing the AST
// System.out.println("-------------------- AST builder -> AST --------------------");
// // System.out.println("AST: " + ast.toString());
// printAST(abstractSyntaxTree, 0);
// System.out.println();
/*
* ------------------------- Semantic Analyzer -> Tast -------------------------
*/
SemanticAnalyzer semanticAnalyzer = new SemanticAnalyzer();
ProgramNode typedAst = (ProgramNode) semanticAnalyzer.generateTast(abstractSyntaxTree);
// Printing the Tast
System.out.println("Tast generated");
/*
* ------------------------- Bytecode Generator -> Bytecode
* -------------------------
*/
ByteCodeGenerator byteCodeGenerator = new ByteCodeGenerator(); ByteCodeGenerator byteCodeGenerator = new ByteCodeGenerator();
if (typedAst != null) //byteCodeGenerator.generateByteCode(abstractSyntaxTree);
byteCodeGenerator.visit(typedAst); byteCodeGenerator.visit(typedAst);
System.out.println("Bytecode generated");
}
/**
* This method is used to print the parse tree in a structured format.
* It recursively traverses the tree and prints the rule names and text of the
* nodes.
*
* @param tree The parse tree to be printed.
* @param parser The parser used to parse the input. It's used to get the rule
* names.
* @param indent The current indentation level. It's used to format the output.
*/
public static void printTree(ParseTree tree, Parser parser, int indent) {
// Create an indentation string based on the current indentation level
String indentString = " ".repeat(indent * 2);
// If the tree node is an instance of RuleContext (i.e., it's an internal node),
// print the rule name
if (tree instanceof RuleContext) {
int ruleIndex = ((RuleContext) tree).getRuleIndex();
String ruleName = parser.getRuleNames()[ruleIndex];
System.out.println(indentString + ruleName);
} else {
// If the tree node is not an instance of RuleContext (i.e., it's a leaf node),
// print the text of the node
System.out.println(indentString + tree.getText());
}
// Recursively print the children of the current node, increasing the
// indentation level
for (int i = 0; i < tree.getChildCount(); i++) {
printTree(tree.getChild(i), parser, indent + 1);
}
}
public static void printAST(ASTNode node, int indent) {
String indentString = " ".repeat(indent * 2);
System.out.println(indentString + node.getClass().toString());
// for (ASTNode child : node.) {
// printAST(child, indent + 1);
// }
} }
} }

View File

@ -1,7 +1,12 @@
package ast; package ast;
public interface ASTNode { //import java.util.List;
public interface ASTNode {
/**
* Please implement this method to return a list of children of each node.
*/
// public List<ASTNode> getChildren();
} }

View File

@ -1,29 +0,0 @@
package ast;
import semantic.SemanticVisitor;
import typechecker.TypeCheckResult;
import visitor.Visitable;
public class VarNode implements ASTNode, Visitable {
private String identifier;
private String type;
public VarNode(String type, String identifier){
this.type = type;
this.identifier = identifier;
}
public String getType(){
return type;
}
public String getIdentifier(){
return identifier;
}
@Override
public TypeCheckResult accept(SemanticVisitor visitor) {
return visitor.analyze(this);
}
}

View File

@ -7,9 +7,9 @@ import visitor.Visitable;
public class BinaryExpressionNode implements ExpressionNode, Visitable { public class BinaryExpressionNode implements ExpressionNode, Visitable {
public ExpressionNode left; public ExpressionNode left;
public ExpressionNode right; public ExpressionNode right;
public String operator; // Stores the operator as a string (e.g., "+", "-", "&&") public ExpresssionOperator operator; // Stores the operator as a string (e.g., "+", "-", "&&")
public BinaryExpressionNode(ExpressionNode left, ExpressionNode right, String operator) { public BinaryExpressionNode(ExpressionNode left, ExpressionNode right, ExpresssionOperator operator) {
this.left = left; this.left = left;
this.right = right; this.right = right;
this.operator = operator; this.operator = operator;

View File

@ -0,0 +1,14 @@
package ast.expression;
public enum ExpresssionOperator {
DOT, // .
PLUS, // +
MINUS, // -
MULTIPLY, // *
DIVIDE, // /
NOT, // !
ASSIGNMENT, // =
EQUALS, // ==
UNEQUALS, // !=
ERROR //TODO: Remove This
}

View File

@ -18,3 +18,5 @@ public class UnaryExpressionNode implements ExpressionNode, Visitable {
return visitor.analyze(this); return visitor.analyze(this);
} }
} }

View File

@ -1,17 +1,14 @@
package ast.statement; package ast.statement;
import ast.VarNode; import ast.expression.BinaryExpressionNode;
import ast.expression.ExpressionNode;
import semantic.SemanticVisitor; import semantic.SemanticVisitor;
import typechecker.TypeCheckResult; import typechecker.TypeCheckResult;
import visitor.Visitable; import visitor.Visitable;
public class AssignmentStatementNode extends StatementNode implements Visitable { public class AssignmentStatementNode extends StatementNode implements Visitable {
public VarNode varNode; public BinaryExpressionNode expression;
public ExpressionNode expression;
public AssignmentStatementNode(VarNode varNode, ExpressionNode expression) { public AssignmentStatementNode(BinaryExpressionNode expression) {
this.varNode = varNode;
this.expression = expression; this.expression = expression;
} }

View File

@ -3,6 +3,7 @@ package parser;
import ast.*; import ast.*;
import ast.expression.BinaryExpressionNode; import ast.expression.BinaryExpressionNode;
import ast.expression.ExpressionNode; import ast.expression.ExpressionNode;
import ast.expression.ExpresssionOperator;
import ast.expression.IdentifierExpressionNode; import ast.expression.IdentifierExpressionNode;
import ast.expression.UnaryExpressionNode; import ast.expression.UnaryExpressionNode;
import ast.member.FieldNode; import ast.member.FieldNode;
@ -137,14 +138,14 @@ public class ASTBuilder extends SimpleJavaBaseVisitor<ASTNode> {
@Override @Override
public ASTNode visitAssignmentStatement(SimpleJavaParser.AssignmentStatementContext ctx) { public ASTNode visitAssignmentStatement(SimpleJavaParser.AssignmentStatementContext ctx) {
VarNode varNode = (VarNode) visit(ctx.var());
ExpressionNode expression = (ExpressionNode) visit(ctx.expression()); BinaryExpressionNode expression = (BinaryExpressionNode) visit(ctx.expression());
return new AssignmentStatementNode(varNode, expression); return new AssignmentStatementNode(expression);
} }
@Override @Override
public ASTNode visitVar(SimpleJavaParser.VarContext ctx) { public ASTNode visitVar(SimpleJavaParser.VarContext ctx) {
return new VarNode("int", ctx.getText()); return null;
} }
@Override @Override
@ -180,8 +181,7 @@ public class ASTBuilder extends SimpleJavaBaseVisitor<ASTNode> {
if (ctx.getChildCount() == 3 && ctx.getChild(1) instanceof TerminalNode) { if (ctx.getChildCount() == 3 && ctx.getChild(1) instanceof TerminalNode) {
ExpressionNode left = (ExpressionNode) visit(ctx.expression(0)); ExpressionNode left = (ExpressionNode) visit(ctx.expression(0));
ExpressionNode right = (ExpressionNode) visit(ctx.expression(1)); ExpressionNode right = (ExpressionNode) visit(ctx.expression(1));
String operator = ctx.getChild(1).getText(); return new BinaryExpressionNode(left, right, ExpresssionOperator.ERROR);
return new BinaryExpressionNode(left, right, operator);
} }
// Handle unary operations // Handle unary operations
else if (ctx.getChildCount() == 2) { else if (ctx.getChildCount() == 2) {

View File

@ -22,12 +22,12 @@ import typechecker.TypeCheckResult;
public class SemanticAnalyzer implements SemanticVisitor { public class SemanticAnalyzer implements SemanticVisitor {
private ArrayList<String> currentFields = new ArrayList<>(); private static ArrayList<String> currentFields = new ArrayList<>();
public static ArrayList<Exception> errors = new ArrayList<>(); public static ArrayList<Exception> errors = new ArrayList<>();
private Scope currentScope; private static Scope currentScope;
private ClassNode currentClass; private static ClassNode currentClass;
public static ASTNode generateTast(ASTNode node) { public static ASTNode generateTast(ASTNode node) {
SemanticAnalyzer semanticCheck = new SemanticAnalyzer(); SemanticAnalyzer semanticCheck = new SemanticAnalyzer();
@ -43,6 +43,13 @@ public class SemanticAnalyzer implements SemanticVisitor {
return null; return null;
} }
public static void clearAnalyzier(){
currentFields.clear();
errors.clear();
currentScope = null;
currentClass = null;
}
@Override @Override
public TypeCheckResult analyze(ProgramNode node) { public TypeCheckResult analyze(ProgramNode node) {
@ -138,21 +145,17 @@ public class SemanticAnalyzer implements SemanticVisitor {
@Override @Override
public TypeCheckResult analyze(AssignmentStatementNode assignmentStatementNode) { public TypeCheckResult analyze(AssignmentStatementNode assignmentStatementNode) {
if (assignmentStatementNode.expression instanceof LiteralNode literalNode) { boolean valid = true;
TypeCheckResult varResult = assignmentStatementNode.varNode.accept(this); BinaryExpressionNode binaryExpressionNode = assignmentStatementNode.expression;
TypeCheckResult expressionResult = assignmentStatementNode.expression.accept(this); var result = binaryExpressionNode.accept(this);
} valid = valid && result.isValid();
return new TypeCheckResult(true, null); return new TypeCheckResult(valid, null);
}
@Override
public TypeCheckResult analyze(VarNode toCheck) {
return new TypeCheckResult(true, null);
} }
@Override @Override
public TypeCheckResult analyze(BinaryExpressionNode toCheck) { public TypeCheckResult analyze(BinaryExpressionNode toCheck) {
return null; boolean valid = true;
return new TypeCheckResult(valid, null);
} }
@Override @Override

View File

@ -3,7 +3,6 @@ package semantic;
import ast.ClassNode; import ast.ClassNode;
import ast.ProgramNode; import ast.ProgramNode;
import ast.VarNode;
import ast.expression.BinaryExpressionNode; import ast.expression.BinaryExpressionNode;
import ast.expression.IdentifierExpressionNode; import ast.expression.IdentifierExpressionNode;
import ast.expression.UnaryExpressionNode; import ast.expression.UnaryExpressionNode;
@ -24,8 +23,6 @@ public interface SemanticVisitor {
TypeCheckResult analyze(AssignmentStatementNode toCheck); TypeCheckResult analyze(AssignmentStatementNode toCheck);
TypeCheckResult analyze(VarNode toCheck);
TypeCheckResult analyze(BinaryExpressionNode toCheck); TypeCheckResult analyze(BinaryExpressionNode toCheck);
TypeCheckResult analyze(IdentifierExpressionNode toCheck); TypeCheckResult analyze(IdentifierExpressionNode toCheck);

View File

@ -2,9 +2,17 @@ public class Example {
public int a; public int a;
public static int testMethod(char x, int a){ public static int testMethod(char x){
} }
} }
public class Test {
public static int testMethod(char x, int a){
}
}

View File

@ -17,6 +17,12 @@
## Scanner Output ## Scanner Output
### Beispiel 1: Empty Class ### Beispiel 1: Empty Class
Token Type; Token Text
Type gibts nur bei Terminalen, Text bei allen
[null "public", null "class", IDENTIFIER "Name", null "{", null "}", EOF "<EOF>"]
Bsp von Ihm mal:
[TokPublic,TokClass,TokIdentifier "Name",TokLeftBrace,TokRightBrace] [TokPublic,TokClass,TokIdentifier "Name",TokLeftBrace,TokRightBrace]
### Beispiel 2: Filled Class ### Beispiel 2: Filled Class

Binary file not shown.

View File

@ -1,4 +1,4 @@
public class EmptyClassExample { public class EmptyClassExample {
private class Inner { private class Inner {
} }
} } // -o für outout

View File

@ -0,0 +1,72 @@
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
import org.antlr.v4.runtime.CharStream;
import org.antlr.v4.runtime.CharStreams;
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.Paths;
import java.util.Arrays;
import java.util.List;
public class FailureTest {
private static final List<String> TEST_FILES = Arrays.asList(
"src/main/test/resources/failureTests/TestClass1.java",
"src/main/test/resources/failureTests/TestClass2.java",
"src/main/test/resources/failureTests/TestClass3.java",
"src/main/test/resources/failureTests/TestClass4.java",
"src/main/test/resources/failureTests/TestClass5.java",
"src/main/test/resources/failureTests/TestClass6.java",
"src/main/test/resources/failureTests/TestClass7.java",
"src/main/test/resources/failureTests/TestClass8.java",
"src/main/test/resources/failureTests/TestClass9.java",
"src/main/test/resources/failureTests/TestClass10.java",
"src/main/test/resources/failureTests/TestClass11.java"
);
/**
* 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 invalidJavaFilesTest() {
// Get the system Java compiler
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
// Assert that the compiler is available
assertNotNull(compiler, "Java Compiler is not available");
// Iterate over the test files
for (String fileName : TEST_FILES) {
// Create a File object for the current file
File file = new File(fileName);
// 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 = compiler.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 " + fileName);
}
}
// schmeißt John Fehler, wenn namen doppelt sind?
// Input: ParseTree mit genanntem Fehler
// Output: Fehlermeldung
@Test
void typedASTTest() throws IOException {
CharStream codeCharStream = null;
try {
codeCharStream = CharStreams.fromPath(Paths.get("src/main/test/resources/EmptyClassExample.java"));
Main.parsefile(codeCharStream);
} catch (IOException e) {
System.err.println("Error reading the file: " + e.getMessage());
}
}
}

View File

@ -21,7 +21,7 @@ public class MainTest {
void testEmptyClass() { void testEmptyClass() {
CharStream codeCharStream = null; CharStream codeCharStream = null;
try { try {
codeCharStream = CharStreams.fromPath(Paths.get("src/main/test/java/EmptyClassExample.java")); codeCharStream = CharStreams.fromPath(Paths.get("src/main/test/resources/EmptyClassExample.java"));
Main.parsefile(codeCharStream); Main.parsefile(codeCharStream);
} catch (IOException e) { } catch (IOException e) {
System.err.println("Error reading the file: " + e.getMessage()); System.err.println("Error reading the file: " + e.getMessage());

View File

@ -1,5 +1,11 @@
public class Tester { public class Tester {
public static void main(String[] args) { public static void main(String[] args) {
new EmptyClassExample(); new EmptyClassExample();
// cp mitgeben
} }
} }
// java -jar pfadtocompiler.jar EmptyClass.java
//mit bash scipt ode rmakefile test automatisieren
//mvn package
// javac tester // tester compilen
// java tester // tester ausführen

View File

View File

@ -1,3 +1,5 @@
package resources;
public class AllFeaturesClassExample { public class AllFeaturesClassExample {
int a; int a;
boolean b; boolean b;

View File

@ -0,0 +1,25 @@
package resources;
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();
}
}

View File

@ -1,3 +1,5 @@
package resources;
public class MoreFeaturesClassExample { public class MoreFeaturesClassExample {
int hallo; int hallo;
private class Inner { private class Inner {

View File

@ -0,0 +1,6 @@
// Syntax Error: Missing semicolon
public class TestClass1 {
public static void main(String[] args) {
System.out.println("Hello, World!") // Missing semicolon here
}
}

View File

@ -0,0 +1,10 @@
// Semantic Error: Non-static method called from static context
public class TestClass10 {
public static void main(String[] args) {
greet(); // Non-static method 'greet' cannot be referenced from a static context
}
public void greet() {
System.out.println("Hi!");
}
}

View File

@ -0,0 +1,10 @@
//Compile error: (4, 9) java: variable number is already defined in method main(java.lang.String[])
public class TestClass10 {
public static void main(String[] args) {
// Declare and initialize an integer variable named 'number' with the value 12
int number = 12;
// This line will cause a compile-time error because 'number' is already defined in this scope
int number =13;
}
}

View File

@ -0,0 +1,6 @@
// Syntax Error: Unclosed string literal
public class TestClass2 {
public static void main(String[] args) {
System.out.println("Hello, World!); // Unclosed string literal
}
}

View File

@ -0,0 +1,10 @@
// Syntax Error: Missing parentheses in method declaration
public class TestClass3 {
public static void main(String[] args) {
System.out.println("Hello, World!");
}
public void greet { // Missing parentheses
System.out.println("Hi!");
}
}

View File

@ -0,0 +1,4 @@
// Syntax Error: Missing class body
public class TestClass4 {-
// Missing class body
}

View File

@ -0,0 +1,7 @@
// Semantic Error: Variable used before declaration
public class TestClass5 {
public static void main(String[] args) {
System.out.println(number); // Variable 'number' used before declaration
int number = 10;
}
}

View File

@ -0,0 +1,10 @@
// Semantic Error: Method with wrong return type
public class TestClass6 {
public static void main(String[] args) {
System.out.println("Hello, World!");
}
public int greet() { // Method should return int, but no return statement is provided
System.out.println("Hi!");
}
}

View File

@ -0,0 +1,5 @@
// Syntax Error: Unmatched braces
public class TestClass7 {
public static void main(String[] args) {
System.out.println("Hello, World!");
// Missing closing brace for the class

View File

@ -0,0 +1,14 @@
// Semantic Error: Duplicate method definition
public class TestClass8 {
public static void main(String[] args) {
System.out.println("Hello, World!");
}
public void greet() {
System.out.println("Hi!");
}
public void greet() { // Duplicate method definition
System.out.println("Hello!");
}
}

View File

@ -0,0 +1,6 @@
// Syntax Error: Incompatible types
public class TestClass9 {
public static void main(String[] args) {
int number = "Hello"; // Incompatible types: String cannot be converted to int
}
}

View File

@ -0,0 +1,24 @@
package resources.featureTests;
public class BooleanOperations {
boolean flag;
public BooleanOperations(boolean flag) {
this.flag = flag;
}
public boolean isFlag() {
return flag;
}
public void toggleFlag() {
flag = !flag;
}
public static void main(String[] args) {
BooleanOperations obj = new BooleanOperations(true);
System.out.println(obj.isFlag());
obj.toggleFlag();
System.out.println(obj.isFlag());
}
}

View File

@ -0,0 +1,24 @@
package resources.featureTests;
public class CharManipulation {
char letter;
public CharManipulation(char letter) {
this.letter = letter;
}
public char getLetter() {
return letter;
}
public void setLetter(char letter) {
this.letter = letter;
}
public static void main(String[] args) {
CharManipulation obj = new CharManipulation('A');
System.out.println(obj.getLetter());
obj.setLetter('B');
System.out.println(obj.getLetter());
}
}

View File

@ -0,0 +1,30 @@
package resources.featureTests;
public class ConditionalStatements {
int number;
public ConditionalStatements(int number) {
this.number = number;
}
public void checkNumber() {
if (number > 0) {
System.out.println("The number is positive.");
} else if (number < 0) {
System.out.println("The number is negative.");
} else {
System.out.println("The number is zero.");
}
}
public static void main(String[] args) {
ConditionalStatements obj1 = new ConditionalStatements(5);
ConditionalStatements obj2 = new ConditionalStatements(-3);
ConditionalStatements obj3 = new ConditionalStatements(0);
obj1.checkNumber();
obj2.checkNumber();
obj3.checkNumber();
}
}

View File

@ -0,0 +1,18 @@
package resources.featureTests;
public class LoopExamples {
public static void main(String[] args) {
// For loop example
for (int i = 0; i < 5; i++) {
System.out.println("For loop iteration: " + i);
}
// While loop example
int j = 0;
while (j < 5) {
System.out.println("While loop iteration: " + j);
j++;
}
}
}

View File

@ -0,0 +1,18 @@
package resources.featureTests;
public class MethodOverloading {
public int add(int a, int b) {
return a + b;
}
public int add(int a, int b, int c) {
return a + b + c;
}
public static void main(String[] args) {
MethodOverloading obj = new MethodOverloading();
System.out.println("Sum of 2 and 3: " + obj.add(2, 3));
System.out.println("Sum of 1, 2, and 3: " + obj.add(1, 2, 3));
}
}

View File

@ -0,0 +1,107 @@
package semantic;
import ast.*;
import ast.expression.BinaryExpressionNode;
import ast.expression.ExpressionNode;
import ast.expression.ExpresssionOperator;
import ast.expression.IdentifierExpressionNode;
import ast.member.FieldNode;
import ast.member.MemberNode;
import ast.member.MethodNode;
import ast.parameter.ParameterListNode;
import ast.parameter.ParameterNode;
import ast.statement.AssignmentStatementNode;
import ast.statement.StatementNode;
import ast.type.AccessTypeNode;
import ast.type.BaseTypeNode;
import ast.type.EnumAccessTypeNode;
import ast.type.EnumTypeNode;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import semantic.exeptions.AlreadyDeclearedException;
import java.util.ArrayList;
import java.util.List;
import static org.junit.jupiter.api.Assertions.assertEquals;
public class SemanticTest {
@BeforeEach
public void init() {
SemanticAnalyzer.clearAnalyzier();
}
@Test
public void alreadyDeclaredLocalFieldVar(){
ProgramNode programNode = new ProgramNode();
List<ClassNode> classList = new ArrayList<ClassNode>();
AccessTypeNode accessTypeNode = new AccessTypeNode(EnumAccessTypeNode.PUBLIC);
ClassNode classNode = new ClassNode(accessTypeNode, "testClass");
MemberNode memberNode1 = new FieldNode(accessTypeNode, new BaseTypeNode(EnumTypeNode.INT), "testVar");
classNode.members.add(memberNode1);
MemberNode memberNode2 = new FieldNode(accessTypeNode, new BaseTypeNode(EnumTypeNode.INT), "testVar");
classNode.members.add(memberNode2);
classList.add(classNode);
programNode.classes = classList;
ASTNode typedAst = SemanticAnalyzer.generateTast(programNode);
assertEquals(1, SemanticAnalyzer.errors.size());
assertEquals(true, SemanticAnalyzer.errors.get(0) instanceof AlreadyDeclearedException);
assertEquals(null, typedAst);
}
@Test
public void shouldWorkWithNoError(){
ProgramNode programNode = new ProgramNode();
List<ClassNode> classList = new ArrayList<ClassNode>();
AccessTypeNode accessTypeNode = new AccessTypeNode(EnumAccessTypeNode.PUBLIC);
ClassNode classNode = new ClassNode(accessTypeNode, "testClass");
MemberNode memberNode1 = new FieldNode(accessTypeNode, new BaseTypeNode(EnumTypeNode.INT), "testVar1");
classNode.members.add(memberNode1);
MemberNode memberNode2 = new FieldNode(accessTypeNode, new BaseTypeNode(EnumTypeNode.INT), "testVar2");
classNode.members.add(memberNode2);
List<ParameterNode> parameterNodeList = new ArrayList<ParameterNode>();
ParameterNode parameterNode1 = new ParameterNode(new BaseTypeNode(EnumTypeNode.INT), "param1");
parameterNodeList.add(parameterNode1);
ParameterListNode parameterListNode = new ParameterListNode(parameterNodeList);
List<StatementNode> statementNodeList = new ArrayList<StatementNode>();
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);
StatementNode statementNode1 = new AssignmentStatementNode(expressionNode);
statementNodeList.add(statementNode1);
MemberNode memberNode3 = new MethodNode(accessTypeNode, new BaseTypeNode(EnumTypeNode.INT), "testVar2",parameterListNode, statementNodeList );
classNode.members.add(memberNode3);
classList.add(classNode);
programNode.classes = classList;
ASTNode typedAst = SemanticAnalyzer.generateTast(programNode);
assertEquals(0, SemanticAnalyzer.errors.size());
assertEquals(programNode, typedAst);
}
}