diff --git a/AlgebraicDataflowArchitectureModel/src/code/ast/Assignment.java b/AlgebraicDataflowArchitectureModel/src/code/ast/Assignment.java new file mode 100644 index 0000000..a7a2fc9 --- /dev/null +++ b/AlgebraicDataflowArchitectureModel/src/code/ast/Assignment.java @@ -0,0 +1,37 @@ +package code.ast; + +/** + * Represents an assignment expression node in AST (Abstract Syntax Tree) + * + * @author s-yamagiwa + */ +public class Assignment extends Expression { + private Expression left; + private Expression right; + + public Assignment(Expression left, Expression right) { + this.left = left; + this.right = right; + } + + public Expression getLeft() { + return left; + } + + public void setLeft(Expression left) { + this.left = left; + } + + public Expression getRight() { + return right; + } + + public void setRight(Expression right) { + this.right = right; + } + + @Override + public String toString() { + return left.toString() + " " + "+" + " " + right.toString(); + } +} diff --git a/AlgebraicDataflowArchitectureModel/src/code/ast/BooleanLiteral.java b/AlgebraicDataflowArchitectureModel/src/code/ast/BooleanLiteral.java deleted file mode 100644 index 53c1bbe..0000000 --- a/AlgebraicDataflowArchitectureModel/src/code/ast/BooleanLiteral.java +++ /dev/null @@ -1,27 +0,0 @@ -package code.ast; - -/** - * Represents a boolean literal in the abstract syntax tree (AST). - * - * @author s-yamagiwa - */ -public class BooleanLiteral extends Expression { - private boolean value; - - public BooleanLiteral(boolean value) { - this.value = value; - } - - public boolean getValue() { - return value; - } - - public void setValue(boolean value) { - this.value = value; - } - - @Override - public String toString() { - return Boolean.toString(value); - } -} diff --git a/AlgebraicDataflowArchitectureModel/src/code/ast/ClassInstanceCreation.java b/AlgebraicDataflowArchitectureModel/src/code/ast/ClassInstanceCreation.java new file mode 100644 index 0000000..fe20607 --- /dev/null +++ b/AlgebraicDataflowArchitectureModel/src/code/ast/ClassInstanceCreation.java @@ -0,0 +1,59 @@ +package code.ast; + +import java.util.List; + +public class ClassInstanceCreation extends Expression { + private Type type; + + private List arguments; + + public ClassInstanceCreation(Type type) { + this(type, List.of()); + } + + public ClassInstanceCreation(Type type, List arguments) { + this.type = type; + this.arguments = arguments; + } + + public Type getType() { + return type; + } + + public void setType(Type type) { + this.type = type; + } + + public List getArguments() { + return arguments; + } + + public void setArguments(List arguments) { + this.arguments = arguments; + } + + public void addArgument(Expression expression) { + arguments.add(expression); + } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + + builder.append("new "); + builder.append(type.toString()); + builder.append("("); + for (int i = 0; i < arguments.size(); i++) { + Expression argument = arguments.get(i); + + builder.append(argument.toString()); + + if (i < arguments.size() - 1) { + builder.append(", "); + } + } + builder.append(")"); + + return builder.toString(); + } +} diff --git a/AlgebraicDataflowArchitectureModel/src/code/ast/FieldAccess.java b/AlgebraicDataflowArchitectureModel/src/code/ast/FieldAccess.java new file mode 100644 index 0000000..bfae25d --- /dev/null +++ b/AlgebraicDataflowArchitectureModel/src/code/ast/FieldAccess.java @@ -0,0 +1,45 @@ +package code.ast; + +/** + * Represents field accesses in AST (Abstract Syntax Tree) + * + * @author s-yamagiwa + */ +public class FieldAccess extends Expression { + private Expression expression; + + private String fieldName; + + public FieldAccess(String fieldName) { + this(null, fieldName); + } + + public FieldAccess(Expression expression, String fieldName) { + this.expression = expression; + this.fieldName = fieldName; + } + + public Expression getExpression() { + return expression; + } + + public void setExpression(Expression expression) { + this.expression = expression; + } + + public String getFieldName() { + return fieldName; + } + + public void setFieldName(String fieldName) { + this.fieldName = fieldName; + } + + @Override + public String toString() { + if (expression == null) { + return fieldName; + } + return expression + "." + fieldName; + } +} diff --git a/AlgebraicDataflowArchitectureModel/src/code/ast/InfixExpression.java b/AlgebraicDataflowArchitectureModel/src/code/ast/InfixExpression.java new file mode 100644 index 0000000..8aa90be --- /dev/null +++ b/AlgebraicDataflowArchitectureModel/src/code/ast/InfixExpression.java @@ -0,0 +1,50 @@ +package code.ast; + +import models.algebra.Symbol; + +/** + * Represents an infix expression in AST (Abstract Syntax Tree) + * + * @author s-yamagiwa + */ +public class InfixExpression extends Expression { + private Symbol operator; + + private Expression leftOperand; + private Expression rightOperand; + + public InfixExpression(Symbol operator, Expression leftOperand, Expression rightOperand) { + this.operator = operator; + this.leftOperand = leftOperand; + this.rightOperand = rightOperand; + } + + public Symbol getOperator() { + return this.operator; + } + + public void setOperator(Symbol operator) { + this.operator = operator; + } + + public Expression getLeftOperand() { + return leftOperand; + } + + public void setLeftOperand(Expression expression) { + this.leftOperand = expression; + } + + public Expression getRightOperand() { + return rightOperand; + } + + public void setRightOperand(Expression expression) { + this.rightOperand = expression; + } + + @Override + public String toString() { + return leftOperand.toString() + " " + operator.toString() + " " + rightOperand.toString(); + } +} diff --git a/AlgebraicDataflowArchitectureModel/src/code/ast/MethodInvocation.java b/AlgebraicDataflowArchitectureModel/src/code/ast/MethodInvocation.java new file mode 100644 index 0000000..94c90e1 --- /dev/null +++ b/AlgebraicDataflowArchitectureModel/src/code/ast/MethodInvocation.java @@ -0,0 +1,91 @@ +package code.ast; + +import java.util.List; + +/** + * Represents a method invocation in AST (Abstract Syntax Tree) + * + * @author s-yamagiwa + * @apiNote Type arguments aren't supported because it isn't necessary in DTRAM code generator. + */ +public class MethodInvocation extends Expression { + /** + * The receiver expression of the invocation + * defaults to {@code null} + */ + private Expression receiver; + + /** + * The method name to be called by this invocation + */ + private String methodName; + + /** + * All arguments used in the called method + */ + private List arguments; + + public MethodInvocation(String methodName) { + this(null, methodName); + } + + public MethodInvocation(Expression receiver, String methodName) { + this(receiver, methodName, List.of()); + } + + public MethodInvocation(Expression receiver, String methodName, List arguments) { + this.receiver = receiver; + this.methodName = methodName; + this.arguments = arguments; + } + + public Expression getReceiver() { + return receiver; + } + + public void setReceiver(Expression receiver) { + this.receiver = receiver; + } + + public String getMethodName() { + return methodName; + } + + public void setMethodName(String methodName) { + this.methodName = methodName; + } + + public List getArguments() { + return arguments; + } + + public void setArguments(List arguments) { + this.arguments = arguments; + } + + @Override + public String toString() { + if (receiver == null) { + StringBuilder builder = new StringBuilder(); + + builder.append(methodName).append("("); + + if (!arguments.isEmpty()) { + for (int i = 0; i < arguments.size(); i++) { + Expression argument = arguments.get(i); + + builder.append(argument.toString()); + + if (i < arguments.size() - 1) { + builder.append(", "); + } + } + } + + builder.append(");"); + + return builder.toString(); + } + return super.toString(); + } +} diff --git a/AlgebraicDataflowArchitectureModel/src/code/ast/NullLiteral.java b/AlgebraicDataflowArchitectureModel/src/code/ast/NullLiteral.java deleted file mode 100644 index d7aa1b3..0000000 --- a/AlgebraicDataflowArchitectureModel/src/code/ast/NullLiteral.java +++ /dev/null @@ -1,13 +0,0 @@ -package code.ast; - -/** - * Represents a {@code null} in the AST. - * - * @author s-yamagiwa - */ -public class NullLiteral extends Expression { - @Override - public String toString() { - return "null"; - } -} diff --git a/AlgebraicDataflowArchitectureModel/src/code/ast/NumberLiteral.java b/AlgebraicDataflowArchitectureModel/src/code/ast/NumberLiteral.java deleted file mode 100644 index a437c0a..0000000 --- a/AlgebraicDataflowArchitectureModel/src/code/ast/NumberLiteral.java +++ /dev/null @@ -1,61 +0,0 @@ -package code.ast; - -/** - * Represents a numeric literal expression in the AST. - * - * @author s-yamagiwa - */ -public class NumberLiteral extends Expression { - /** - * Represents the raw string value of a numeric token in the source code. - * This variable stores the literal text that defines a numeric value, including - * any prefixes, suffixes, or delimiters used in the representation of the number. - */ - private String tokenValue; - - /** - * Constructs a new NumberLiteral instance with the specified token value. - * - * @param tokenValue - The literal text representing the numeric value in the source code. - */ - public NumberLiteral(String tokenValue) { - setTokenValue(tokenValue); - } - - /** - * Retrieves the raw string value of the numeric token in the source code. - * - * @return The raw string value of the numeric token. - */ - public String getTokenValue() { - return tokenValue; - } - - /** - * Sets the raw string value of the numeric token in the source code. - * - * @param tokenValue - The raw string value of the numeric token. - * @throws IllegalArgumentException if the specified token value is null, empty, or invalid number representation in Java source code. - */ - public void setTokenValue(String tokenValue) { - if (tokenValue == null) { - throw new IllegalArgumentException("Token value must not be null."); - } - - int length = tokenValue.length(); - if (length == 0) { - throw new IllegalArgumentException("Token value must not be empty."); - } - - if (NumberUtil.isDecimalNumber(tokenValue) || NumberUtil.isBinaryNumber(tokenValue) || NumberUtil.isOctalNumber(tokenValue) || NumberUtil.isHexNumber(tokenValue)) { - this.tokenValue = tokenValue; - } else { - throw new IllegalArgumentException("Invalid number literal: " + tokenValue); - } - } - - @Override - public String toString() { - return tokenValue; - } -} diff --git a/AlgebraicDataflowArchitectureModel/src/code/ast/NumberUtil.java b/AlgebraicDataflowArchitectureModel/src/code/ast/NumberUtil.java deleted file mode 100644 index 4137a35..0000000 --- a/AlgebraicDataflowArchitectureModel/src/code/ast/NumberUtil.java +++ /dev/null @@ -1,251 +0,0 @@ -package code.ast; - -/** - * Utility class that provides methods for number-related operations. - * - * @author s-yamagiwa - */ -public class NumberUtil { - /** - * Determines whether the given string is a valid binary number. - * A valid binary number starts with "0b" or "0B", followed by a - * combination of digits (0 or 1) or underscores ('_'), - * with restrictions on the positioning of underscores. - * - * @param token The string to be evaluated as a binary number. - * @return {@code true} if the given string represents a valid binary number, - * {@code false} otherwise. - * @apiNote This method returns {@code true} if the given token is a valid binary number representation in Java source code. - * Therefore, the validation rules strictly adhere to the Java language specification. - */ - public static boolean isBinaryNumber(String token) { - if (token == null) { - return false; - } - - int length = token.length(); - if (length < 3) { - return false; - } - - Lexer lexer = new Lexer(token.toLowerCase()); - - if (lexer.peek() != '0' || lexer.peekNext() != 'b') { - return false; - } - - lexer.advance(); // 0 - lexer.advance(); // b - - // Check for cases like 0b or 0b_ (Invalid underscore position) - if (lexer.peek() == '\0' || lexer.peek() == '_') { - return false; - } - - char prev = 'b'; // Initialize the previous character as 'b' - boolean hasDigit = false; - - while (lexer.peek() != '\0') { - char c = lexer.advance(); - - // Check for long number suffix - if (c == 'l') { - // The suffix for a long literal must be the last character in the literal. - if (lexer.peek() != '\0') { - return false; - } - - // The suffix must NOT be placed immediately after an underscore - if (prev == '_') { - return false; - } - - // Valid suffix found; finish checking - break; - } - - boolean isDigit = c == '0' || c == '1'; - boolean isValidFormat = isDigit || (c == '_'); - - if (!isValidFormat) { - return false; - } - - if (isDigit) { - hasDigit = true; - } - - // Save the previous character - prev = c; - } - - // Check for cases like 0b0101_ (Invalid trailing underscore) - if (prev == '_') { - return false; - } - - if (!hasDigit) { - return false; - } - - return true; - } - - /** - * Check whether the given string is a valid octal number or not. - * A valid octal number starts with '0' and is followed by a - * combination of digits (0 to 7) or underscores ('_'), - * with restrictions on the positioning of underscores. - * - * @param token The string to be evaluated as an octal number. - * @return {@code true} if the given string represents a valid octal number, - * {@code false} otherwise. - * @apiNote This method returns {@code true} if the given token is a valid octal number representation in Java source code. - * Therefore, the validation rules strictly adhere to the Java language specification. - */ - public static boolean isOctalNumber(String token) { - if (token == null) { - return false; - } - - int length = token.length(); - if (length < 1) { - return false; - } - - Lexer lexer = new Lexer(token.toLowerCase()); - - // Octal numbers must start with '0' - if (lexer.peek() != '0') { - return false; - } - - while (lexer.peek() != '\0') { - if (lexer.peek() == '_' && lexer.peekNext() == '\0') { - return false; - } - if (lexer.peek() == '_' && lexer.peekNext() == 'l') { - return false; - } - - if (lexer.peek() == 'l' && lexer.peekNext() == '\0') { - break; - } - - boolean isDigit = lexer.peek() >= '0' && lexer.peek() <= '7'; - boolean isValidFormat = isDigit || lexer.peek() == '_'; - - if (!isValidFormat) { - return false; - } - - lexer.advance(); - } - - return true; - } - - public static boolean isDecimalNumber(String token) { - if (token == null || token.isBlank()) { - return false; - } - - // Multiples dots are not allowed - String[] tokens = token.split("\\.", -1); - if (tokens.length > 2) { - return false; - } - - Lexer integerPart = new Lexer(tokens[0].toLowerCase()); - Lexer fractionalPart = new Lexer(tokens[1].toLowerCase()); - - // TODO: Implement validation logic - - return true; - } - - /** - * Determines whether the given string is a valid hexadecimal number. - * A valid hexadecimal number starts with "0x" or "0X", followed by a - * combination of digits (0-9), letters (a-f, A-F), or underscores ('_'), - * with restrictions on the positioning of underscores. - * - * @param token The string to be evaluated as a hexadecimal number. - * @return {@code true} if the given string represents a valid hexadecimal number, - * {@code false} otherwise. - * @apiNote This method returns {@code true} if the given token is a valid hexadecimal number representation in Java source code. - * Therefore, the validation rules strictly adhere to the Java language specification. Hexadecimal floating-point is not supported yet. - */ - public static boolean isHexNumber(String token) { - if (token == null) { - return false; - } - - int length = token.length(); - if (length < 3) { - return false; - } - - Lexer lexer = new Lexer(token.toLowerCase()); - - if (lexer.peek() != '0' || lexer.peekNext() != 'x') { - return false; - } - - lexer.advance(); // 0 - lexer.advance(); // x - - // Check for cases like 0x or 0x_ (Invalid underscore position) - if (lexer.peek() == '\0' || lexer.peek() == '_') { - return false; - } - - char prev = 'x'; // Initialize the previous character as 'x' - boolean hasDigit = false; - - while (lexer.peek() != '\0') { - char c = lexer.advance(); - - // Check for long number suffix - if (c == 'l') { - // The suffix for a long literal must be the last character in the literal. - if (lexer.peek() != '\0') { - return false; - } - - // The suffix must NOT be placed immediately after an underscore - if (prev == '_') { - return false; - } - - // Valid suffix found; finish checking - break; - } - - boolean isDigit = (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f'); - boolean isValidFormat = isDigit || (c == '_'); - - if (!isValidFormat) { - return false; - } - - if (isDigit) { - hasDigit = true; - } - - // Save the previous character - prev = c; - } - - // Check for cases like 0xFFFFF_ (Invalid trailing underscore) - if (prev == '_') { - return false; - } - - if (!hasDigit) { - return false; - } - - return true; - } -} diff --git a/AlgebraicDataflowArchitectureModel/src/code/ast/ParenthesizedExpression.java b/AlgebraicDataflowArchitectureModel/src/code/ast/ParenthesizedExpression.java new file mode 100644 index 0000000..a7b50cb --- /dev/null +++ b/AlgebraicDataflowArchitectureModel/src/code/ast/ParenthesizedExpression.java @@ -0,0 +1,28 @@ +package code.ast; + +/** + * Represents a parenthesized expression in AST (Abstract Syntax Tree) + * This class is used to save the priority of each expression + * + * @author s-yamagiwa + */ +public class ParenthesizedExpression extends Expression { + private Expression expression; + + public ParenthesizedExpression(Expression expression) { + this.expression = expression; + } + + public Expression getExpression() { + return expression; + } + + public void setExpression(Expression expression) { + this.expression = expression; + } + + @Override + public String toString() { + return "(" + expression.toString() + ")"; + } +} diff --git a/AlgebraicDataflowArchitectureModel/src/code/ast/PostfixExpression.java b/AlgebraicDataflowArchitectureModel/src/code/ast/PostfixExpression.java new file mode 100644 index 0000000..bc520ac --- /dev/null +++ b/AlgebraicDataflowArchitectureModel/src/code/ast/PostfixExpression.java @@ -0,0 +1,53 @@ +package code.ast; + +/** + * Represents a postfix expression in AST (Abstract Syntax Tree) + * + * @author s-yamagiwa + */ +public class PostfixExpression extends Expression { + public enum Operator { + INCREMENT("++"), DECREMENT("--"); + + Operator(String symbol) { + this.symbol = symbol; + } + + private final String symbol; + + @Override + public String toString() { + return symbol; + } + } + + private Expression operand; + + private Operator operator; + + public PostfixExpression(Expression operand, Operator operator) { + this.operand = operand; + this.operator = operator; + } + + public Expression getOperand() { + return operand; + } + + public void setOperand(Expression operand) { + this.operand = operand; + } + + public Operator getOperator() { + return operator; + } + + public void setOperator(Operator operator) { + this.operator = operator; + } + + @Override + public String toString() { + return operand.toString() + operator.toString(); + } +} diff --git a/AlgebraicDataflowArchitectureModel/src/code/ast/PrefixExpression.java b/AlgebraicDataflowArchitectureModel/src/code/ast/PrefixExpression.java new file mode 100644 index 0000000..2e854b7 --- /dev/null +++ b/AlgebraicDataflowArchitectureModel/src/code/ast/PrefixExpression.java @@ -0,0 +1,53 @@ +package code.ast; + +/** + * Represents a prefix expression in AST (Abstract Syntax Tree) + * + * @author s-yamagiwa + */ +public class PrefixExpression extends Expression { + public enum Operator { + INCREMENT("++"), DECREMENT("--"), PLUS("+"), MINUS("-"), NOT("!"); + + Operator(String symbol) { + this.symbol = symbol; + } + + private final String symbol; + + @Override + public String toString() { + return symbol; + } + } + + private Expression operand; + + private Operator operator; + + public PrefixExpression(Expression operand, Operator operator) { + this.operand = operand; + this.operator = operator; + } + + public Expression getOperand() { + return operand; + } + + public void setOperand(Expression operand) { + this.operand = operand; + } + + public Operator getOperator() { + return operator; + } + + public void setOperator(Operator operator) { + this.operator = operator; + } + + @Override + public String toString() { + return operator.toString() + operand.toString(); + } +} diff --git a/AlgebraicDataflowArchitectureModel/src/code/ast/PrimitiveType.java b/AlgebraicDataflowArchitectureModel/src/code/ast/PrimitiveType.java index 9a80598..b8d252e 100644 --- a/AlgebraicDataflowArchitectureModel/src/code/ast/PrimitiveType.java +++ b/AlgebraicDataflowArchitectureModel/src/code/ast/PrimitiveType.java @@ -10,24 +10,24 @@ * @author s-yamagiwa */ public class PrimitiveType extends AnnotatableType { - private SimpleName name; + private models.algebra.Type type; - public PrimitiveType(SimpleName name) { - this.name = name; + public PrimitiveType(models.algebra.Type type) { + this.type = type; } - public SimpleName getName() { - return name; + public models.algebra.Type getType() { + return type; } - public void setName(SimpleName name) { - this.name = name; + public void setType(models.algebra.Type type) { + this.type = type; } @Override public String toString() { if (getAnnotations().isEmpty()) { - return name.getIdentifier(); + return type.getTypeName(); } StringBuilder builder = new StringBuilder(); @@ -35,7 +35,7 @@ builder.append(annotation.toString()); builder.append(" "); } - builder.append(name.getIdentifier()); + builder.append(type.getTypeName()); return builder.toString(); } diff --git a/AlgebraicDataflowArchitectureModel/src/code/ast/SimpleName.java b/AlgebraicDataflowArchitectureModel/src/code/ast/SimpleName.java deleted file mode 100644 index e8de874..0000000 --- a/AlgebraicDataflowArchitectureModel/src/code/ast/SimpleName.java +++ /dev/null @@ -1,45 +0,0 @@ -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 index 7e66ae4..3451ee3 100644 --- a/AlgebraicDataflowArchitectureModel/src/code/ast/SimpleType.java +++ b/AlgebraicDataflowArchitectureModel/src/code/ast/SimpleType.java @@ -7,24 +7,24 @@ * @author s-yamagiwa */ public class SimpleType extends AnnotatableType { - private SimpleName name; + private String name; - public SimpleType(SimpleName name) { + public SimpleType(String name) { this.name = name; } - public SimpleName getName() { + public String getName() { return name; } - public void setName(SimpleName name) { + public void setName(String name) { this.name = name; } @Override public String toString() { if (getAnnotations().isEmpty()) { - return name.getIdentifier(); + return name; } StringBuilder builder = new StringBuilder(); @@ -32,7 +32,7 @@ builder.append(annotation.toString()); builder.append(" "); } - builder.append(name.getIdentifier()); + builder.append(name); return builder.toString(); } diff --git a/AlgebraicDataflowArchitectureModel/src/code/ast/StringLiteral.java b/AlgebraicDataflowArchitectureModel/src/code/ast/StringLiteral.java deleted file mode 100644 index 9ebc74b..0000000 --- a/AlgebraicDataflowArchitectureModel/src/code/ast/StringLiteral.java +++ /dev/null @@ -1,180 +0,0 @@ -package code.ast; - -/** - * Represents a string literal, including its escaped syntax as it appears in the source code. - * - * @author s-yamagiwa - */ -public class StringLiteral extends Expression { - /** - * The literal string with its quotes and escapes. - * Defaults to the literal for the empty string {@code "\"\""}. - */ - private String escapedValue; - - /** - * Constructs a new, empty StringLiteral instance. The default value - * of the literal is an empty string, represented as {@code "\"\""} with - * quotes and escapes included. - */ - public StringLiteral() { - this("\"\""); - } - - /** - * Constructs a new StringLiteral instance with the specified string literal token. - * - * @param escapedValue the string value of the literal, including enclosing - * double quotes and embedded escape sequences - */ - public StringLiteral(String escapedValue) { - this.escapedValue = escapedValue; - } - - /** - * Retrieves the escaped string value of this literal, including its enclosing - * double quotes and embedded escape sequences as it appears in the source code. - * - * @return The escaped string value with quotes and escape sequences. - */ - public String getEscapedValue() { - return escapedValue; - } - - /** - * Sets the escaped value of the string literal. The escaped value - * represents the string, including its enclosing double quotes and - * any embedded escape sequences. - * - * @param escapedValue the new escaped string value, including - * its quotes and escape sequences - */ - public void setEscapedValue(String escapedValue) { - this.escapedValue = escapedValue; - } - - /** - * Retrieves the literal string value of this string literal. The literal value - * does not include enclosing double quotes or escape sequences. - * - * @return The literal string value without enclosing double quotes or escape sequences. - */ - public String getLiteralValue() { - int length = escapedValue.length(); - if (length < 2) { - throw new IllegalArgumentException("Invalid string literal: " + escapedValue); - } - - char first = escapedValue.charAt(0); - char last = escapedValue.charAt(length - 1); - if (first != '\"' || last != '\"') { - throw new IllegalArgumentException("Invalid string literal: " + escapedValue); - } - - StringBuilder sb = new StringBuilder(); - for (int i = 1; i < length - 1; i++) { - char c = escapedValue.charAt(i); - - // If the character is not an escape sequence, just append it - if (c != '\\') { - sb.append(c); - continue; - } - - i++; - if (i < length - 1) { - char next = escapedValue.charAt(i); - switch (next) { - case 'n': - sb.append('\n'); - break; - case 'r': - sb.append('\r'); - break; - case 't': - sb.append('\t'); - break; - case 'b': - sb.append('\b'); - break; - case 'f': - sb.append('\f'); - break; - case '\\': - sb.append('\\'); - break; - case '\"': - sb.append('\"'); - break; - case '\'': - sb.append('\''); - break; - default: - // If it's not a known escape sequence, just append the backslash and the character - sb.append('\\'); - sb.append(next); - } - } else { - sb.append('\\'); - } - } - return sb.toString(); - } - - /** - * Sets the literal string value for this instance. The provided string is processed - * to escape any special characters such as newlines, tabs, and quotes. - * This ensures the string is correctly represented as a literal, with appropriate - * escape sequences included. - * - * @param literalValue the literal string value to set. Special characters in the - * string are escaped, and the resulting value is enclosed in - * double quotes. - */ - public void setLiteralValue(String literalValue) { - StringBuilder sb = new StringBuilder(); - sb.append('\"'); - for (int i = 0; i < literalValue.length(); i++) { - char c = literalValue.charAt(i); - switch (c) { - case '\n': - sb.append("\\n"); - break; - case '\r': - sb.append("\\r"); - break; - case '\t': - sb.append("\\t"); - break; - case '\b': - sb.append("\\b"); - break; - case '\f': - sb.append("\\f"); - break; - case '\\': - sb.append("\\\\"); - break; - case '\"': - sb.append("\\\""); - break; - default: - sb.append(c); - } - } - sb.append('\"'); - - this.escapedValue = sb.toString(); - } - - /** - * Retrieves the string value of this literal node with its quotes and escapes, - * which appears in the actual source code. - * - * @return The string value with its quotes and escapes. - */ - @Override - public String toString() { - return escapedValue; - } -} diff --git a/AlgebraicDataflowArchitectureModel/src/code/ast/SuperMethodInvocation.java b/AlgebraicDataflowArchitectureModel/src/code/ast/SuperMethodInvocation.java new file mode 100644 index 0000000..e7e3573 --- /dev/null +++ b/AlgebraicDataflowArchitectureModel/src/code/ast/SuperMethodInvocation.java @@ -0,0 +1,62 @@ +package code.ast; + +import java.util.List; + +/** + * Represents a super method invocation in AST (Abstract Syntax Tree) + * + * @author s-yamagiwa + * @apiNote Type arguments aren't supported because it isn't necessary in DTRAM code generator. + */ +public class SuperMethodInvocation extends Expression { + private String methodName; + private List arguments; + + public SuperMethodInvocation(String methodName) { + this(methodName, List.of()); + } + + public SuperMethodInvocation(String methodName, List arguments) { + this.methodName = methodName; + this.arguments = arguments; + } + + public String getMethodName() { + return methodName; + } + + public void setMethodName(String methodName) { + this.methodName = methodName; + } + + public List getArguments() { + return arguments; + } + + public void setArguments(List arguments) { + this.arguments = arguments; + } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + + builder.append("super.").append(methodName).append("("); + + if (!arguments.isEmpty()) { + for (int i = 0; i < arguments.size(); i++) { + Expression argument = arguments.get(i); + + builder.append(argument.toString()); + + if (i < arguments.size() - 1) { + builder.append(", "); + } + } + } + + builder.append(");"); + + return builder.toString(); + } +} diff --git a/AlgebraicDataflowArchitectureModel/src/code/ast/ThisExpression.java b/AlgebraicDataflowArchitectureModel/src/code/ast/ThisExpression.java new file mode 100644 index 0000000..aad8ee8 --- /dev/null +++ b/AlgebraicDataflowArchitectureModel/src/code/ast/ThisExpression.java @@ -0,0 +1,4 @@ +package code.ast; + +public class ThisExpression extends Expression { +} diff --git a/AlgebraicDataflowArchitectureModel/src/code/ast/Type.java b/AlgebraicDataflowArchitectureModel/src/code/ast/Type.java index bdf304b..7861acc 100644 --- a/AlgebraicDataflowArchitectureModel/src/code/ast/Type.java +++ b/AlgebraicDataflowArchitectureModel/src/code/ast/Type.java @@ -34,11 +34,4 @@ 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/tests/NumberUtilTest.java b/AlgebraicDataflowArchitectureModel/src/tests/NumberUtilTest.java deleted file mode 100644 index 1733d1b..0000000 --- a/AlgebraicDataflowArchitectureModel/src/tests/NumberUtilTest.java +++ /dev/null @@ -1,126 +0,0 @@ -package tests; - -import code.ast.NumberUtil; -import org.junit.Test; - -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; - -public class NumberUtilTest { - @Test - public void testIsHexNumber() { - // --- Valid format numbers --- - assertTrue("Standard hex", NumberUtil.isHexNumber("0x123456789ABCDEF")); - assertTrue("Mixed case prefix", NumberUtil.isHexNumber("0Xabcdef")); - assertTrue("Hex with underscores", NumberUtil.isHexNumber("0x123_456")); - assertTrue("Hex with long suffix (L)", NumberUtil.isHexNumber("0x123L")); - assertTrue("Hex with long suffix (l)", NumberUtil.isHexNumber("0x123l")); - assertTrue("Minimum valid hex", NumberUtil.isHexNumber("0x0")); - assertTrue("Successive underscores", NumberUtil.isHexNumber("0x123__456")); - - // --- Invalid format numbers --- - // Null and empty - assertFalse("Null string", NumberUtil.isHexNumber(null)); - assertFalse("Empty string", NumberUtil.isHexNumber("")); - assertFalse("Prefix only", NumberUtil.isHexNumber("0x")); - - // Incorrect prefix - assertFalse("Missing prefix", NumberUtil.isHexNumber("123")); - assertFalse("Invalid prefix (0y)", NumberUtil.isHexNumber("0y123")); - assertFalse("Leading space", NumberUtil.isHexNumber(" 0x123")); - - // Invalid characters - assertFalse("Invalid character (g)", NumberUtil.isHexNumber("0x12g")); - assertFalse("Decimal point", NumberUtil.isHexNumber("0x1.2")); - - // Underscore placement rules - assertFalse("Underscore immediately after prefix", NumberUtil.isHexNumber("0x_123")); - assertFalse("Trailing underscore", NumberUtil.isHexNumber("0x123_")); - assertFalse("Trailing underscore with L", NumberUtil.isHexNumber("0x123_L")); - - // Long suffix rules - assertFalse("L in middle", NumberUtil.isHexNumber("0x1L2")); - assertFalse("Multiple L", NumberUtil.isHexNumber("0x1LL")); - assertFalse("L with invalid char", NumberUtil.isHexNumber("0x1GL")); - - // No digits - assertFalse("No hex digits (0xL)", NumberUtil.isHexNumber("0xL")); - } - - @Test - public void testIsBinaryNumber() { - // --- Valid format numbers --- - assertTrue("Standard binary", NumberUtil.isBinaryNumber("0b10101010")); - assertTrue("Mixed case prefix", NumberUtil.isBinaryNumber("0B1100")); - assertTrue("Binary with underscores", NumberUtil.isBinaryNumber("0b1_0_1")); - assertTrue("Binary with long suffix (L)", NumberUtil.isBinaryNumber("0b101L")); - assertTrue("Binary with long suffix (l)", NumberUtil.isBinaryNumber("0b110l")); - assertTrue("Minimum valid binary", NumberUtil.isBinaryNumber("0b0")); - assertTrue("Successive underscores", NumberUtil.isBinaryNumber("0b101__010")); - - // --- Invalid format numbers --- - // Null and empty - assertFalse("Null string", NumberUtil.isBinaryNumber(null)); - assertFalse("Empty string", NumberUtil.isBinaryNumber("")); - assertFalse("Prefix only", NumberUtil.isBinaryNumber("0b")); - - // Incorrect prefix - assertFalse("Missing prefix", NumberUtil.isBinaryNumber("101")); - assertFalse("Invalid prefix (0x)", NumberUtil.isBinaryNumber("0x101")); - assertFalse("Leading space", NumberUtil.isBinaryNumber(" 0b101")); - - // Invalid characters - assertFalse("Invalid character (2)", NumberUtil.isBinaryNumber("0b102")); - assertFalse("Invalid character (a)", NumberUtil.isBinaryNumber("0b10a")); - assertFalse("Decimal point", NumberUtil.isBinaryNumber("0b1.0")); - - // Underscore placement rules - assertFalse("Underscore immediately after prefix", NumberUtil.isBinaryNumber("0b_101")); - assertFalse("Trailing underscore", NumberUtil.isBinaryNumber("0b101_")); - assertFalse("Trailing underscore with L", NumberUtil.isBinaryNumber("0b101_L")); - - // Long suffix rules - assertFalse("L in middle", NumberUtil.isBinaryNumber("0b1L0")); - assertFalse("Multiple L", NumberUtil.isBinaryNumber("0b1LL")); - assertFalse("L with invalid char", NumberUtil.isBinaryNumber("0b12L")); - - // No digits - assertFalse("No binary digits (0bL)", NumberUtil.isBinaryNumber("0bL")); - } - - @Test - public void testIsOctalNumber() { - // --- Valid format numbers --- - assertTrue("Standard octal", NumberUtil.isOctalNumber("01234567")); - assertTrue("Octal with underscores", NumberUtil.isOctalNumber("01_23_4")); - assertTrue("Octal with long suffix (L)", NumberUtil.isOctalNumber("0123L")); - assertTrue("Octal with long suffix (l)", NumberUtil.isOctalNumber("0123l")); - assertTrue("Minimum octal number (0)", NumberUtil.isOctalNumber("0")); - assertTrue("Successive underscores", NumberUtil.isOctalNumber("0123__456")); - - // --- Invalid format numbers --- - // Null and empty - assertFalse("Null string", NumberUtil.isOctalNumber(null)); - assertFalse("Empty string", NumberUtil.isOctalNumber("")); - - // Incorrect prefix - assertFalse("Does not start with 0", NumberUtil.isOctalNumber("123")); - assertFalse("Leading space", NumberUtil.isOctalNumber(" 0123")); - - // Invalid characters - assertFalse("Invalid character (8)", NumberUtil.isOctalNumber("0128")); - assertFalse("Invalid character (a)", NumberUtil.isOctalNumber("012a")); - assertFalse("Decimal point", NumberUtil.isOctalNumber("01.2")); - - // Underscore placement rules - assertTrue("Underscore immediately after 0 is valid for octal", NumberUtil.isOctalNumber("0_123")); - assertFalse("Trailing underscore", NumberUtil.isOctalNumber("0123_")); - assertFalse("Trailing underscore with L", NumberUtil.isOctalNumber("0123_L")); - - // Long suffix rules - assertFalse("L in middle", NumberUtil.isOctalNumber("01L2")); - assertFalse("Multiple L", NumberUtil.isOctalNumber("01LL")); - assertFalse("L with invalid char", NumberUtil.isOctalNumber("018L")); - assertTrue("L with the minimum number (0L)", NumberUtil.isOctalNumber("0L")); - } -}