diff --git a/AlgebraicDataflowArchitectureModel/src/code/ast/AnnotatableType.java b/AlgebraicDataflowArchitectureModel/src/code/ast/AnnotatableType.java new file mode 100644 index 0000000..6e87c83 --- /dev/null +++ b/AlgebraicDataflowArchitectureModel/src/code/ast/AnnotatableType.java @@ -0,0 +1,26 @@ +package code.ast; + +import java.util.ArrayList; +import java.util.List; + +/** + * Represents an abstract base class for AST types that can have annotations. + * This class extends the functionality of {@link Type} by introducing support + * for attaching annotations to the type. + *

+ * Subclasses of this class represent specific kinds of types in the AST that + * allow annotations, such as primitive types or other specialized types. + * + * @author s-yamagiwa + */ +public abstract class AnnotatableType extends Type { + private final List annotations = new ArrayList<>(); + + public void addAnnotation(Annotation annotation) { + annotations.add(annotation); + } + + public List getAnnotations() { + return annotations; + } +} diff --git a/AlgebraicDataflowArchitectureModel/src/code/ast/Block.java b/AlgebraicDataflowArchitectureModel/src/code/ast/Block.java index 2b4f654..844691d 100644 --- a/AlgebraicDataflowArchitectureModel/src/code/ast/Block.java +++ b/AlgebraicDataflowArchitectureModel/src/code/ast/Block.java @@ -2,31 +2,88 @@ import java.util.List; import java.util.ArrayList; +import java.util.stream.Collectors; -public class Block extends ASTNode { - private List statements = new ArrayList(); +public class Block extends Statement { + private List statements = new ArrayList(); - public List getStatements() { + public List getStatements2() { return statements; } - public void setStatements(List statements) { + public void setStatements(List statements) { this.statements = statements; } - public void addFirstStatement(String statement) { + public void addFirstStatement(Statement statement) { statements.add(0, statement); } - - public void addStatement(String statement) { + + public void addStatement(Statement statement) { statements.add(statement); } - - public String toString() { - String code = ""; - for (String statement: statements) { - code += (statement + "\n"); + + public void addFirstStatements(List statements) { + this.statements.addAll(0, statements); + } + + public void addStatements(List statements) { + this.statements.addAll(statements); + } + + //==================================================== + //TODO: CodeGenerator修正後削除 + + public List getStatements() { + List strings = new ArrayList<>(); + for (Statement stmt : statements) { + if (stmt != null) { + strings.add(stmt.toString()); + } } - return code; + return strings; + } + + public void addFirstStatement(String code) { + if (code != null) { + this.addFirstStatement(new Statement() { + @Override + public String toString() { + return code; + } + }.toString()); + } + } + + public void addStatement(String code) { + if (code != null) { + this.addStatement(new PlainStatement(code)); + } + } + + //==================================================== + + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("{\n"); + + for (Statement statement : statements) { + if (statement != null) { + String content = statement.toString(); + + // split statement + String[] lines = content.split("\n"); + + // Tab + for (String line : lines) { + sb.append("\t").append(line).append("\n"); + } + } + } + + sb.append("}"); + return sb.toString(); } } diff --git a/AlgebraicDataflowArchitectureModel/src/code/ast/EnhancedForStatement.java b/AlgebraicDataflowArchitectureModel/src/code/ast/EnhancedForStatement.java new file mode 100644 index 0000000..e1d1b42 --- /dev/null +++ b/AlgebraicDataflowArchitectureModel/src/code/ast/EnhancedForStatement.java @@ -0,0 +1,22 @@ +package code.ast; + +public class EnhancedForStatement extends Statement { + + private VariableDeclaration singleVariableDeclaration; + private Statement expression; + private Statement body; + + public VariableDeclaration getParameter() { return singleVariableDeclaration; } + public void setParameter(VariableDeclaration parameter) { this.singleVariableDeclaration = parameter; } + + public Statement getExpression() { return expression; } + public void setExpression(Statement expression) { this.expression = expression; } + + public Statement getBody() { return body; } + public void setBody(Statement body) { this.body = body; } + + @Override + public String toString() { + return "for (" + singleVariableDeclaration + " : " + expression + ") " + body; + } +} diff --git a/AlgebraicDataflowArchitectureModel/src/code/ast/Expression.java b/AlgebraicDataflowArchitectureModel/src/code/ast/Expression.java new file mode 100644 index 0000000..d492947 --- /dev/null +++ b/AlgebraicDataflowArchitectureModel/src/code/ast/Expression.java @@ -0,0 +1,9 @@ +package code.ast; + +/** + * Abstract base class for all expression nodes in the abstract syntax tree (AST). + * + * @author s-yamagiwa + */ +public abstract class Expression extends ASTNode { +} diff --git a/AlgebraicDataflowArchitectureModel/src/code/ast/ExpressionStatement.java b/AlgebraicDataflowArchitectureModel/src/code/ast/ExpressionStatement.java new file mode 100644 index 0000000..1d23a01 --- /dev/null +++ b/AlgebraicDataflowArchitectureModel/src/code/ast/ExpressionStatement.java @@ -0,0 +1,13 @@ +package code.ast; + +public class ExpressionStatement extends Statement{ + private Statement expression; + + public Statement getExpression() { return expression; } + public void setExpression(Statement expression) { this.expression = expression; } + + @Override + public String toString() { + return expression + ";"; + } +} diff --git a/AlgebraicDataflowArchitectureModel/src/code/ast/ForStatement.java b/AlgebraicDataflowArchitectureModel/src/code/ast/ForStatement.java new file mode 100644 index 0000000..bf736a5 --- /dev/null +++ b/AlgebraicDataflowArchitectureModel/src/code/ast/ForStatement.java @@ -0,0 +1,69 @@ +package code.ast; + +import java.util.ArrayList; +import java.util.List; + +public class ForStatement extends Statement { + + private List initializers = new ArrayList<>(); + private Statement condition; + private List updaters = new ArrayList<>(); + private Statement body; + + public List getInitializers() { + return initializers; + } + + public void setInitializers(List initializers) { + this.initializers = initializers; + } + + public Statement getCondition() { + return condition; + } + + public void setCondition(Statement condition) { + this.condition = condition; + } + + public List getUpdaters() { + return updaters; + } + + public void setUpdaters(List updaters) { + this.updaters = updaters; + } + + public Statement getBody() { + return body; + } + + public void setBody(Statement body) { + this.body = body; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("for ("); + + for (int i = 0; i < initializers.size(); i++) { + sb.append(initializers.get(i)); + if (i < initializers.size() - 1) sb.append(", "); + } + sb.append("; "); + + if (condition != null) sb.append(condition); + sb.append("; "); + + for (int i = 0; i < updaters.size(); i++) { + sb.append(updaters.get(i)); + if (i < updaters.size() - 1) sb.append(", "); + } + sb.append(") "); + + if (body != null) sb.append(body); + + return sb.toString(); + } +} \ No newline at end of file diff --git a/AlgebraicDataflowArchitectureModel/src/code/ast/IfStatement.java b/AlgebraicDataflowArchitectureModel/src/code/ast/IfStatement.java new file mode 100644 index 0000000..e7521f1 --- /dev/null +++ b/AlgebraicDataflowArchitectureModel/src/code/ast/IfStatement.java @@ -0,0 +1,43 @@ +package code.ast; + +public class IfStatement extends Statement { + + private Statement expression; + private Statement thenStatement; + private Statement elseStatement; + + public Statement getExpression() { + return expression; + } + + public void setExpression(Statement expression) { + this.expression = expression; + } + + public Statement getThenStatement() { + return thenStatement; + } + + public void setThenStatement(Statement thenStatement) { + this.thenStatement = thenStatement; + } + + public Statement getElseStatement() { + return elseStatement; + } + + public void setElseStatement(Statement elseStatement) { + this.elseStatement = elseStatement; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("if (").append(expression).append(") "); + sb.append(thenStatement); + if (elseStatement != null) { + sb.append(" else ").append(elseStatement); + } + return sb.toString(); + } +} \ No newline at end of file diff --git a/AlgebraicDataflowArchitectureModel/src/code/ast/MethodDeclaration.java b/AlgebraicDataflowArchitectureModel/src/code/ast/MethodDeclaration.java index 5f5aafc..b541ce6 100644 --- a/AlgebraicDataflowArchitectureModel/src/code/ast/MethodDeclaration.java +++ b/AlgebraicDataflowArchitectureModel/src/code/ast/MethodDeclaration.java @@ -142,21 +142,18 @@ } code += (name + "("); if (parameters != null) { - String delimitar = ""; - for (VariableDeclaration parameter: parameters) { - code = code + delimitar + parameter.toString(); - delimitar = ", "; + for (int i = 0; i < parameters.size(); i++) { + code += parameters.get(i).toString(); + if (i < parameters.size() - 1) code += ", "; } } code += ") "; - if (thrws != null) { - code += thrws.toString() + " "; - } - code += "{\n"; + if (body != null) { - code += CodeUtil.insertTab(body.toString()); + code += body.toString(); + } else { + code += ";"; } - code += "}"; return code; } } diff --git a/AlgebraicDataflowArchitectureModel/src/code/ast/ParameterizedType.java b/AlgebraicDataflowArchitectureModel/src/code/ast/ParameterizedType.java new file mode 100644 index 0000000..dbb16e2 --- /dev/null +++ b/AlgebraicDataflowArchitectureModel/src/code/ast/ParameterizedType.java @@ -0,0 +1,92 @@ +package code.ast; + +import java.util.List; + +/** + * Represents a parameterized type in an abstract syntax tree (AST). + * A parameterized type consists of a base type and a set of type arguments. + *

+ * For example, List<String> is a parameterized type where + * List is the base type and String is the type argument. + * + * @author s-yamagiwa + */ +public class ParameterizedType extends Type { + /** + * The base type of the parameterized type. + *

+ * For example, List in List<String> is a base type. + */ + private Type type; + + /** + * The type arguments of the parameterized type. + * Defaults to an empty list. + *

+ * For example, String in List<String> is a type argument. + */ + private List typeArguments; + + public ParameterizedType(Type type, List typeArguments) { + this.type = type; + this.typeArguments = typeArguments; + } + + public ParameterizedType(Type type) { + this(type, List.of()); + } + + /** + * Adds a type argument to the parameterized type. + * + * @param type The type argument to add. Only {@link SimpleType}s are allowed for now. + */ + public void addTypeArgument(Type type) { + typeArguments.add(type); + } + + public Type getType() { + return type; + } + + public void setType(Type type) { + this.type = type; + } + + /** + * Returns the type arguments of the parameterized type. + * Only {@link SimpleType}s are allowed for now. + *

+ * It can be empty if it is the type of created instances like in the following example. + * new List<>() or new HashMap<>() + * + * @return The type arguments of the parameterized type. + */ + public List getTypeArguments() { + return typeArguments; + } + + public void setTypeArguments(List typeArguments) { + this.typeArguments = typeArguments; + } + + @Override + public String toString() { + if (typeArguments.isEmpty()) { + return type.toString(); + } + + StringBuilder builder = new StringBuilder(); + builder.append(type.toString()); + builder.append("<"); + for (int i = 0; i < typeArguments.size(); i++) { + builder.append(typeArguments.get(i).toString()); + if (i < typeArguments.size() - 1) { + builder.append(", "); + } + } + builder.append(">"); + + return builder.toString(); + } +} diff --git a/AlgebraicDataflowArchitectureModel/src/code/ast/PlainStatement.java b/AlgebraicDataflowArchitectureModel/src/code/ast/PlainStatement.java new file mode 100644 index 0000000..edc9ff5 --- /dev/null +++ b/AlgebraicDataflowArchitectureModel/src/code/ast/PlainStatement.java @@ -0,0 +1,18 @@ +package code.ast; + +//==================================================== +//TODO: CodeGenerator修正後削除 +//==================================================== + +public class PlainStatement extends Statement { + private String code; + + public PlainStatement(String code) { + this.code = code; + } + + @Override + public String toString() { + return code; + } +} \ No newline at end of file diff --git a/AlgebraicDataflowArchitectureModel/src/code/ast/PrimitiveType.java b/AlgebraicDataflowArchitectureModel/src/code/ast/PrimitiveType.java new file mode 100644 index 0000000..9a80598 --- /dev/null +++ b/AlgebraicDataflowArchitectureModel/src/code/ast/PrimitiveType.java @@ -0,0 +1,42 @@ +package code.ast; + +/** + * Represents a primitive type in the abstract syntax tree (AST). + * This class extends the {@code AnnotatableType}, allowing annotations + * to be attached to primitive types. + *

+ * Primitive types are: {@code boolean}, {@code byte}, {@code char}, {@code short}, {@code int}, {@code long}, {@code float}, {@code double} and {@code void} + * + * @author s-yamagiwa + */ +public class PrimitiveType extends AnnotatableType { + private SimpleName name; + + public PrimitiveType(SimpleName name) { + this.name = name; + } + + public SimpleName getName() { + return name; + } + + public void setName(SimpleName name) { + this.name = name; + } + + @Override + public String toString() { + if (getAnnotations().isEmpty()) { + return name.getIdentifier(); + } + + StringBuilder builder = new StringBuilder(); + for (Annotation annotation : getAnnotations()) { + builder.append(annotation.toString()); + builder.append(" "); + } + builder.append(name.getIdentifier()); + + return builder.toString(); + } +} \ No newline at end of file diff --git a/AlgebraicDataflowArchitectureModel/src/code/ast/ReturnStatement.java b/AlgebraicDataflowArchitectureModel/src/code/ast/ReturnStatement.java new file mode 100644 index 0000000..501cd26 --- /dev/null +++ b/AlgebraicDataflowArchitectureModel/src/code/ast/ReturnStatement.java @@ -0,0 +1,21 @@ +package code.ast; + +public class ReturnStatement extends Statement{ + private Statement expression; + + public Statement getExpression() { + return expression; + } + + public void setExpression(Statement expression) { + this.expression = expression; + } + + @Override + public String toString() { + if (expression != null) { + return "return " + expression + ";"; + } + return "return;"; + } +} diff --git a/AlgebraicDataflowArchitectureModel/src/code/ast/SimpleName.java b/AlgebraicDataflowArchitectureModel/src/code/ast/SimpleName.java new file mode 100644 index 0000000..e8de874 --- /dev/null +++ b/AlgebraicDataflowArchitectureModel/src/code/ast/SimpleName.java @@ -0,0 +1,45 @@ +package code.ast; + +/** + * AST Node for identifiers such as types, variables, and methods. + * + * @author s-yamagiwa + */ +public class SimpleName extends Expression { + private String identifier; + + /** + * Indicates whether this name represents a variable or not, default to false. + */ + private boolean isVar = false; + + public SimpleName(String identifier) { + this.identifier = identifier; + } + + public SimpleName(String identifier, boolean isVar) { + this(identifier); + this.isVar = isVar; + } + + public String getIdentifier() { + return identifier; + } + + public void setIdentifier(String identifier) { + this.identifier = identifier; + } + + public boolean isVar() { + return isVar; + } + + public void setVar(boolean isVar) { + this.isVar = isVar; + } + + @Override + public String toString() { + return identifier; + } +} diff --git a/AlgebraicDataflowArchitectureModel/src/code/ast/SimpleType.java b/AlgebraicDataflowArchitectureModel/src/code/ast/SimpleType.java new file mode 100644 index 0000000..7e66ae4 --- /dev/null +++ b/AlgebraicDataflowArchitectureModel/src/code/ast/SimpleType.java @@ -0,0 +1,39 @@ +package code.ast; + +/** + * Represents a simple type in the AST, which is a type with a single identifier. + * For example, String, List, Map or MyClass. + * + * @author s-yamagiwa + */ +public class SimpleType extends AnnotatableType { + private SimpleName name; + + public SimpleType(SimpleName name) { + this.name = name; + } + + public SimpleName getName() { + return name; + } + + public void setName(SimpleName name) { + this.name = name; + } + + @Override + public String toString() { + if (getAnnotations().isEmpty()) { + return name.getIdentifier(); + } + + StringBuilder builder = new StringBuilder(); + for (Annotation annotation : getAnnotations()) { + builder.append(annotation.toString()); + builder.append(" "); + } + builder.append(name.getIdentifier()); + + return builder.toString(); + } +} diff --git a/AlgebraicDataflowArchitectureModel/src/code/ast/Statement.java b/AlgebraicDataflowArchitectureModel/src/code/ast/Statement.java new file mode 100644 index 0000000..96d1af1 --- /dev/null +++ b/AlgebraicDataflowArchitectureModel/src/code/ast/Statement.java @@ -0,0 +1,7 @@ +package code.ast; + +public abstract class Statement extends ASTNode { + + @Override + public abstract String toString(); +} diff --git a/AlgebraicDataflowArchitectureModel/src/code/ast/Type.java b/AlgebraicDataflowArchitectureModel/src/code/ast/Type.java new file mode 100644 index 0000000..bdf304b --- /dev/null +++ b/AlgebraicDataflowArchitectureModel/src/code/ast/Type.java @@ -0,0 +1,44 @@ +package code.ast; + +/** + * Represents an abstract base class for all types in an abstract syntax tree (AST). + * A type can represent various forms such as primitive types, simple types, + * parameterized types, or others as defined by subclasses. + * + * @author s-yamagiwa + */ +public abstract class Type extends ASTNode { + /** + * Returns whether this type is a primitive type or not. + * + * @return true if this type is a primitive type, false otherwise. + */ + public final boolean isPrimitiveType() { + return (this instanceof PrimitiveType); + } + + /** + * Returns whether this type is a simple type or not. + * + * @return true if this type is a simple type, false otherwise. + */ + public final boolean isSimpleType() { + return (this instanceof SimpleType); + } + + /** + * Returns whether this type is a parameterized type or not. + * + * @return true if this type is a parameterized type, false otherwise. + */ + public final boolean isParameterizedType() { + return (this instanceof ParameterizedType); + } + + /** + * Returns whether this type is a var or not. + */ + public boolean isVar() { + return false; + } +} \ No newline at end of file diff --git a/AlgebraicDataflowArchitectureModel/src/code/ast/VariableDeclarationStatement.java b/AlgebraicDataflowArchitectureModel/src/code/ast/VariableDeclarationStatement.java new file mode 100644 index 0000000..0348fce --- /dev/null +++ b/AlgebraicDataflowArchitectureModel/src/code/ast/VariableDeclarationStatement.java @@ -0,0 +1,56 @@ +package code.ast; + +import java.util.ArrayList; +import java.util.List; + +public class VariableDeclarationStatement extends Statement { + + private List modifiers = new ArrayList<>(); + private Type type; + private List fragments = new ArrayList<>(); + + public List getModifiers() { + return modifiers; + } + + public void setModifiers(List modifiers) { + this.modifiers = modifiers; + } + + public Type getType() { + return type; + } + + public void setType(Type type) { + this.type = type; + } + + public List getFragments() { + return fragments; + } + + public void setFragments(List fragments) { + this.fragments = fragments; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + + for (Statement mod : modifiers) { + sb.append(mod.toString()).append(" "); + } + + if (type != null) { + sb.append(type.toString()).append(" "); + } + + for (int i = 0; i < fragments.size(); i++) { + sb.append(fragments.get(i).getName()); + if (i < fragments.size() - 1) sb.append(", "); + } + + sb.append(";"); + return sb.toString(); + } +} \ No newline at end of file diff --git a/AlgebraicDataflowArchitectureModel/src/code/ast/WhileStatement.java b/AlgebraicDataflowArchitectureModel/src/code/ast/WhileStatement.java new file mode 100644 index 0000000..be37a35 --- /dev/null +++ b/AlgebraicDataflowArchitectureModel/src/code/ast/WhileStatement.java @@ -0,0 +1,33 @@ +package code.ast; + +public class WhileStatement extends Statement { + + private Statement expression; + private Statement body; + + public Statement getExpression() { + return expression; + } + + public void setExpression(Statement expression) { + this.expression = expression; + } + + public Statement getBody() { + return body; + } + + public void setBody(Statement body) { + this.body = body; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("while (").append(expression).append(") "); + if (body != null) { + sb.append(body); + } + return sb.toString(); + } +} \ No newline at end of file diff --git a/AlgebraicDataflowArchitectureModel/src/tests/ASTTest.java b/AlgebraicDataflowArchitectureModel/src/tests/ASTTest.java new file mode 100644 index 0000000..c29320f --- /dev/null +++ b/AlgebraicDataflowArchitectureModel/src/tests/ASTTest.java @@ -0,0 +1,72 @@ +package tests; + +import code.ast.*; +import models.dataConstraintModel.DataConstraintModel; + +import java.util.Arrays; +import java.util.List; + +public class ASTTest { + public static void main(String[] args) { + + MethodDeclaration method = new MethodDeclaration("Test", false); + Block methodBody = new Block(); + + VariableDeclarationStatement varStmt = new VariableDeclarationStatement(); + varStmt.setModifiers(List.of(new PlainStatement("private"))); + varStmt.setType(new PrimitiveType(new SimpleName("int"))); + varStmt.setFragments(List.of( + new VariableDeclaration(DataConstraintModel.typeInt, "x"), + new VariableDeclaration(DataConstraintModel.typeInt, "sum") + )); + methodBody.addStatement(varStmt); + + ForStatement forStmt = new ForStatement(); + forStmt.setInitializers(Arrays.asList(new PlainStatement("int j = 0"))); + forStmt.setCondition(new PlainStatement("j < 5")); + forStmt.setUpdaters(Arrays.asList(new PlainStatement("j++"))); + Block forBody = new Block(); + forBody.addStatement("sum += j;"); + forStmt.setBody(forBody); + methodBody.addStatement(forStmt); + + EnhancedForStatement enhancedFor = new EnhancedForStatement(); + enhancedFor.setParameter(new VariableDeclaration(DataConstraintModel.typeString, "s")); + enhancedFor.setExpression(new PlainStatement("list")); + Block eForBody = new Block(); + eForBody.addStatement("System.out.println(s);"); + enhancedFor.setBody(eForBody); + methodBody.addStatement(enhancedFor); + + WhileStatement whileStmt = new WhileStatement(); + whileStmt.setExpression(new PlainStatement("sum < 100")); + + Block whileBody = new Block(); + IfStatement ifStmt = new IfStatement(); + ifStmt.setExpression(new PlainStatement("sum % 2 == 0")); + + Block thenBlock = new Block(); + ExpressionStatement exprStmt = new ExpressionStatement(); + exprStmt.setExpression(new PlainStatement("sum += 10")); + thenBlock.addStatement(exprStmt); + + Block elseBlock = new Block(); + elseBlock.addStatement("sum += 5;"); + + ifStmt.setThenStatement(thenBlock); + ifStmt.setElseStatement(elseBlock); + + whileBody.addStatement(ifStmt); + whileStmt.setBody(whileBody); + methodBody.addStatement(whileStmt); + + ReturnStatement returnStmt = new ReturnStatement(); + returnStmt.setExpression(new PlainStatement("sum")); + methodBody.addStatement(returnStmt); + + method.setBody(methodBody); + + System.out.println("--- Generated Code ---"); + System.out.println(method.toString()); + } +} \ No newline at end of file