diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..b63da45
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,42 @@
+.gradle
+build/
+!gradle/wrapper/gradle-wrapper.jar
+!**/src/main/**/build/
+!**/src/test/**/build/
+
+### IntelliJ IDEA ###
+.idea/modules.xml
+.idea/jarRepositories.xml
+.idea/compiler.xml
+.idea/libraries/
+*.iws
+*.iml
+*.ipr
+out/
+!**/src/main/**/out/
+!**/src/test/**/out/
+
+### Eclipse ###
+.apt_generated
+.classpath
+.factorypath
+.project
+.settings
+.springBeans
+.sts4-cache
+bin/
+!**/src/main/**/bin/
+!**/src/test/**/bin/
+
+### NetBeans ###
+/nbproject/private/
+/nbbuild/
+/dist/
+/nbdist/
+/.nb-gradle/
+
+### VS Code ###
+.vscode/
+
+### Mac OS ###
+.DS_Store
\ No newline at end of file
diff --git a/.idea/.gitignore b/.idea/.gitignore
new file mode 100644
index 0000000..d13da9c
--- /dev/null
+++ b/.idea/.gitignore
@@ -0,0 +1,10 @@
+# デフォルトの無視対象ファイル
+/shelf/
+/workspace.xml
+# エディターベースの HTTP クライアントリクエスト
+/httpRequests/
+# 環境に依存する Maven ホームディレクトリのパス
+/mavenHomeManager.xml
+# Datasource local storage ignored files
+/dataSources/
+/dataSources.local.xml
diff --git a/RDLApplicationRuntime/build.gradle b/RDLApplicationRuntime/build.gradle
new file mode 100644
index 0000000..15c9952
--- /dev/null
+++ b/RDLApplicationRuntime/build.gradle
@@ -0,0 +1,16 @@
+plugins {
+ id 'java-library'
+}
+
+repositories {
+ mavenCentral()
+}
+
+dependencies {
+ testImplementation platform('org.junit:junit-bom:5.10.0')
+ testImplementation 'org.junit.jupiter:junit-jupiter'
+}
+
+test {
+ useJUnitPlatform()
+}
\ No newline at end of file
diff --git a/RDLApplicationRuntime/src/main/java/org/nittalab/rdl/applicationruntime/ApplicationRuntime.java b/RDLApplicationRuntime/src/main/java/org/nittalab/rdl/applicationruntime/ApplicationRuntime.java
new file mode 100644
index 0000000..d879dc9
--- /dev/null
+++ b/RDLApplicationRuntime/src/main/java/org/nittalab/rdl/applicationruntime/ApplicationRuntime.java
@@ -0,0 +1,17 @@
+package org.nittalab.rdl.applicationruntime;
+
+public class ApplicationRuntime {
+ private ApplicationState applicationState = new ApplicationState();
+
+ public UIState getUIState() {
+ return applicationState.getUIState();
+ }
+
+ public TableState getTableState() {
+ return applicationState.getTableState();
+ }
+
+ public String getCurTableKey(String tableId) {
+ return null;
+ }
+}
diff --git a/RDLApplicationRuntime/src/main/java/org/nittalab/rdl/applicationruntime/ApplicationState.java b/RDLApplicationRuntime/src/main/java/org/nittalab/rdl/applicationruntime/ApplicationState.java
new file mode 100644
index 0000000..ea5279a
--- /dev/null
+++ b/RDLApplicationRuntime/src/main/java/org/nittalab/rdl/applicationruntime/ApplicationState.java
@@ -0,0 +1,14 @@
+package org.nittalab.rdl.applicationruntime;
+
+public class ApplicationState {
+ private UIState uiState = new UIState();
+ private TableState tableState = new TableState();
+
+ public UIState getUIState() {
+ return uiState;
+ }
+
+ public TableState getTableState() {
+ return tableState;
+ }
+}
diff --git a/RDLApplicationRuntime/src/main/java/org/nittalab/rdl/applicationruntime/ConstraintHandler.java b/RDLApplicationRuntime/src/main/java/org/nittalab/rdl/applicationruntime/ConstraintHandler.java
new file mode 100644
index 0000000..33927b8
--- /dev/null
+++ b/RDLApplicationRuntime/src/main/java/org/nittalab/rdl/applicationruntime/ConstraintHandler.java
@@ -0,0 +1,6 @@
+package org.nittalab.rdl.applicationruntime;
+
+public interface ConstraintHandler {
+ public void beforeEvent();
+ public void afterEvent();
+}
diff --git a/RDLApplicationRuntime/src/main/java/org/nittalab/rdl/applicationruntime/TableState.java b/RDLApplicationRuntime/src/main/java/org/nittalab/rdl/applicationruntime/TableState.java
new file mode 100644
index 0000000..d05b048
--- /dev/null
+++ b/RDLApplicationRuntime/src/main/java/org/nittalab/rdl/applicationruntime/TableState.java
@@ -0,0 +1,11 @@
+package org.nittalab.rdl.applicationruntime;
+
+public class TableState {
+ public String getValue(String tableId, String key, int columnNo) {
+ return null;
+ }
+
+ public void updateValue(String tableId, String key, int columnNo, String value) {
+
+ }
+}
diff --git a/RDLApplicationRuntime/src/main/java/org/nittalab/rdl/applicationruntime/UIState.java b/RDLApplicationRuntime/src/main/java/org/nittalab/rdl/applicationruntime/UIState.java
new file mode 100644
index 0000000..857e135
--- /dev/null
+++ b/RDLApplicationRuntime/src/main/java/org/nittalab/rdl/applicationruntime/UIState.java
@@ -0,0 +1,23 @@
+package org.nittalab.rdl.applicationruntime;
+
+public class UIState {
+ public void changeScreen(String nextScreenId) {
+
+ }
+
+ public String getWidgetText(String screenId, String widgetId) {
+ return null;
+ }
+
+ public void setWidgetText(String screenId, String widgetId, String text) {
+
+ }
+
+ public String getCurWidgetText(String widgetId) {
+ return null;
+ }
+
+ public String getCurWidgetState(String widgetId) {
+ return null;
+ }
+}
diff --git a/RDLApplicationRuntime/src/main/java/org/nittalab/rdl/applicationruntime/WidgetEventReceiver.java b/RDLApplicationRuntime/src/main/java/org/nittalab/rdl/applicationruntime/WidgetEventReceiver.java
new file mode 100644
index 0000000..bd14adc
--- /dev/null
+++ b/RDLApplicationRuntime/src/main/java/org/nittalab/rdl/applicationruntime/WidgetEventReceiver.java
@@ -0,0 +1,5 @@
+package org.nittalab.rdl.applicationruntime;
+
+public interface WidgetEventReceiver {
+ public void onWidgetStateChanged();
+}
diff --git a/build.gradle b/build.gradle
new file mode 100644
index 0000000..d82bd4e
--- /dev/null
+++ b/build.gradle
@@ -0,0 +1,25 @@
+plugins {
+ id 'java'
+ id 'application'
+}
+
+application {
+ mainClass = 'org.nittalab.rdlworkbench.Main'
+}
+
+group = 'org.nittalab'
+version = '1.0-SNAPSHOT'
+
+repositories {
+ mavenCentral()
+}
+
+dependencies {
+ implementation project(':RDLApplicationRuntime')
+ testImplementation platform('org.junit:junit-bom:5.10.0')
+ testImplementation 'org.junit.jupiter:junit-jupiter'
+}
+
+test {
+ useJUnitPlatform()
+}
\ No newline at end of file
diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000..249e583
--- /dev/null
+++ b/gradle/wrapper/gradle-wrapper.jar
Binary files differ
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000..9bc3ee7
--- /dev/null
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Fri Sep 04 18:24:05 JST 2026
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-8.13-bin.zip
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
diff --git a/gradlew b/gradlew
new file mode 100644
index 0000000..1b6c787
--- /dev/null
+++ b/gradlew
@@ -0,0 +1,234 @@
+#!/bin/sh
+
+#
+# Copyright © 2015-2021 the original authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+##############################################################################
+#
+# Gradle start up script for POSIX generated by Gradle.
+#
+# Important for running:
+#
+# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
+# noncompliant, but you have some other compliant shell such as ksh or
+# bash, then to run this script, type that shell name before the whole
+# command line, like:
+#
+# ksh Gradle
+#
+# Busybox and similar reduced shells will NOT work, because this script
+# requires all of these POSIX shell features:
+# * functions;
+# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
+# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
+# * compound commands having a testable exit status, especially «case»;
+# * various built-in commands including «command», «set», and «ulimit».
+#
+# Important for patching:
+#
+# (2) This script targets any POSIX shell, so it avoids extensions provided
+# by Bash, Ksh, etc; in particular arrays are avoided.
+#
+# The "traditional" practice of packing multiple parameters into a
+# space-separated string is a well documented source of bugs and security
+# problems, so this is (mostly) avoided, by progressively accumulating
+# options in "$@", and eventually passing that to Java.
+#
+# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
+# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
+# see the in-line comments for details.
+#
+# There are tweaks for specific operating systems such as AIX, CygWin,
+# Darwin, MinGW, and NonStop.
+#
+# (3) This script is generated from the Groovy template
+# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
+# within the Gradle project.
+#
+# You can find Gradle at https://github.com/gradle/gradle/.
+#
+##############################################################################
+
+# Attempt to set APP_HOME
+
+# Resolve links: $0 may be a link
+app_path=$0
+
+# Need this for daisy-chained symlinks.
+while
+ APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
+ [ -h "$app_path" ]
+do
+ ls=$( ls -ld "$app_path" )
+ link=${ls#*' -> '}
+ case $link in #(
+ /*) app_path=$link ;; #(
+ *) app_path=$APP_HOME$link ;;
+ esac
+done
+
+APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
+
+APP_NAME="Gradle"
+APP_BASE_NAME=${0##*/}
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD=maximum
+
+warn () {
+ echo "$*"
+} >&2
+
+die () {
+ echo
+ echo "$*"
+ echo
+ exit 1
+} >&2
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+nonstop=false
+case "$( uname )" in #(
+ CYGWIN* ) cygwin=true ;; #(
+ Darwin* ) darwin=true ;; #(
+ MSYS* | MINGW* ) msys=true ;; #(
+ NONSTOP* ) nonstop=true ;;
+esac
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD=$JAVA_HOME/jre/sh/java
+ else
+ JAVACMD=$JAVA_HOME/bin/java
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD=java
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
+ case $MAX_FD in #(
+ max*)
+ MAX_FD=$( ulimit -H -n ) ||
+ warn "Could not query maximum file descriptor limit"
+ esac
+ case $MAX_FD in #(
+ '' | soft) :;; #(
+ *)
+ ulimit -n "$MAX_FD" ||
+ warn "Could not set maximum file descriptor limit to $MAX_FD"
+ esac
+fi
+
+# Collect all arguments for the java command, stacking in reverse order:
+# * args from the command line
+# * the main class name
+# * -classpath
+# * -D...appname settings
+# * --module-path (only if needed)
+# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
+
+# For Cygwin or MSYS, switch paths to Windows format before running java
+if "$cygwin" || "$msys" ; then
+ APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
+ CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
+
+ JAVACMD=$( cygpath --unix "$JAVACMD" )
+
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ for arg do
+ if
+ case $arg in #(
+ -*) false ;; # don't mess with options #(
+ /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
+ [ -e "$t" ] ;; #(
+ *) false ;;
+ esac
+ then
+ arg=$( cygpath --path --ignore --mixed "$arg" )
+ fi
+ # Roll the args list around exactly as many times as the number of
+ # args, so each arg winds up back in the position where it started, but
+ # possibly modified.
+ #
+ # NB: a `for` loop captures its iteration list before it begins, so
+ # changing the positional parameters here affects neither the number of
+ # iterations, nor the values presented in `arg`.
+ shift # remove old arg
+ set -- "$@" "$arg" # push replacement arg
+ done
+fi
+
+# Collect all arguments for the java command;
+# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
+# shell script including quotes and variable substitutions, so put them in
+# double quotes to make sure that they get re-expanded; and
+# * put everything else in single quotes, so that it's not re-expanded.
+
+set -- \
+ "-Dorg.gradle.appname=$APP_BASE_NAME" \
+ -classpath "$CLASSPATH" \
+ org.gradle.wrapper.GradleWrapperMain \
+ "$@"
+
+# Use "xargs" to parse quoted args.
+#
+# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
+#
+# In Bash we could simply go:
+#
+# readarray ARGS < <( xargs -n1 <<<"$var" ) &&
+# set -- "${ARGS[@]}" "$@"
+#
+# but POSIX shell has neither arrays nor command substitution, so instead we
+# post-process each arg (as a line of input to sed) to backslash-escape any
+# character that might be a shell metacharacter, then use eval to reverse
+# that process (while maintaining the separation between arguments), and wrap
+# the whole thing up as a single "set" statement.
+#
+# This will of course break if any of these variables contains a newline or
+# an unmatched quote.
+#
+
+eval "set -- $(
+ printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
+ xargs -n1 |
+ sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
+ tr '\n' ' '
+ )" '"$@"'
+
+exec "$JAVACMD" "$@"
diff --git a/gradlew.bat b/gradlew.bat
new file mode 100644
index 0000000..107acd3
--- /dev/null
+++ b/gradlew.bat
@@ -0,0 +1,89 @@
+@rem
+@rem Copyright 2015 the original author or authors.
+@rem
+@rem Licensed under the Apache License, Version 2.0 (the "License");
+@rem you may not use this file except in compliance with the License.
+@rem You may obtain a copy of the License at
+@rem
+@rem https://www.apache.org/licenses/LICENSE-2.0
+@rem
+@rem Unless required by applicable law or agreed to in writing, software
+@rem distributed under the License is distributed on an "AS IS" BASIS,
+@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+@rem See the License for the specific language governing permissions and
+@rem limitations under the License.
+@rem
+
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Resolve any "." and ".." in APP_HOME to make it shorter.
+for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto execute
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto execute
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/settings.gradle b/settings.gradle
new file mode 100644
index 0000000..d652066
--- /dev/null
+++ b/settings.gradle
@@ -0,0 +1,3 @@
+rootProject.name = 'RDLWorkbench'
+
+include 'RDLApplicationRuntime'
\ No newline at end of file
diff --git a/src/main/java/org/nittalab/rdlworkbench/Main.java b/src/main/java/org/nittalab/rdlworkbench/Main.java
new file mode 100644
index 0000000..ec045d0
--- /dev/null
+++ b/src/main/java/org/nittalab/rdlworkbench/Main.java
@@ -0,0 +1,7 @@
+package org.nittalab.rdlworkbench;
+
+public class Main {
+ public static void main(String[] args) {
+
+ }
+}
diff --git a/src/main/java/org/nittalab/rdlworkbench/ast/ASTNode.java b/src/main/java/org/nittalab/rdlworkbench/ast/ASTNode.java
new file mode 100644
index 0000000..e871fc4
--- /dev/null
+++ b/src/main/java/org/nittalab/rdlworkbench/ast/ASTNode.java
@@ -0,0 +1,13 @@
+package org.nittalab.rdlworkbench.ast;
+
+public abstract class ASTNode {
+ private ASTNode parent;
+
+ public ASTNode getParent() {
+ return parent;
+ }
+
+ public void setParent(ASTNode parent) {
+ this.parent = parent;
+ }
+}
diff --git a/src/main/java/org/nittalab/rdlworkbench/ast/AbstractTypeDeclaration.java b/src/main/java/org/nittalab/rdlworkbench/ast/AbstractTypeDeclaration.java
new file mode 100644
index 0000000..6f1e6e7
--- /dev/null
+++ b/src/main/java/org/nittalab/rdlworkbench/ast/AbstractTypeDeclaration.java
@@ -0,0 +1,13 @@
+package org.nittalab.rdlworkbench.ast;
+
+public class AbstractTypeDeclaration extends BodyDeclaration {
+ protected String typeName = null;
+
+ public String getTypeName() {
+ return typeName;
+ }
+
+ public void setTypeName(String typeName) {
+ this.typeName = typeName;
+ }
+}
diff --git a/src/main/java/org/nittalab/rdlworkbench/ast/AnnotatableType.java b/src/main/java/org/nittalab/rdlworkbench/ast/AnnotatableType.java
new file mode 100644
index 0000000..bc16a58
--- /dev/null
+++ b/src/main/java/org/nittalab/rdlworkbench/ast/AnnotatableType.java
@@ -0,0 +1,26 @@
+package org.nittalab.rdlworkbench.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/src/main/java/org/nittalab/rdlworkbench/ast/Annotation.java b/src/main/java/org/nittalab/rdlworkbench/ast/Annotation.java
new file mode 100644
index 0000000..ab4fb9c
--- /dev/null
+++ b/src/main/java/org/nittalab/rdlworkbench/ast/Annotation.java
@@ -0,0 +1,57 @@
+package org.nittalab.rdlworkbench.ast;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+public class Annotation extends ASTNode {
+ private String name = null;
+ private Map keyValueMap = null;
+
+ public Annotation(String name) {
+ this.name = name;
+ keyValueMap = new HashMap<>();
+ }
+
+ public Annotation(String name, String value) {
+ this.name = name;
+ keyValueMap = new HashMap<>();
+ keyValueMap.put("value", value);
+ }
+
+ public String getElementName() {
+ return name;
+ }
+
+ public Map getParams() {
+ return keyValueMap;
+ }
+
+ public Object getValue(String key) {
+ return keyValueMap.get(key);
+ }
+
+ public void addParam(String key, Object value) {
+ keyValueMap.put(key, value);
+ }
+
+ public String toString() {
+ String code = "@" + name;
+ Set keySet = keyValueMap.keySet();
+ if (keySet.size() == 0) {
+ return code;
+ } else if (keySet.size() == 1 && keySet.iterator().next().equals("value")) {
+ code += "(" + keyValueMap.get("value").toString() + ")";
+ } else {
+ code += "(";
+ String delimitar = "";
+ for (String key: keySet) {
+ Object value = keyValueMap.get(key);
+ code += delimitar + key + " = \"" + value.toString() + "\"";
+ delimitar = ", ";
+ }
+ code += ")";
+ }
+ return code;
+ }
+}
diff --git a/src/main/java/org/nittalab/rdlworkbench/ast/Assignment.java b/src/main/java/org/nittalab/rdlworkbench/ast/Assignment.java
new file mode 100644
index 0000000..9285fad
--- /dev/null
+++ b/src/main/java/org/nittalab/rdlworkbench/ast/Assignment.java
@@ -0,0 +1,42 @@
+package org.nittalab.rdlworkbench.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;
+ }
+
+ @Override
+ public Expression replace(Variable variable, Expression expression) {
+ return new Assignment(left.replace(variable, expression), right.replace(variable, expression));
+ }
+
+ 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/src/main/java/org/nittalab/rdlworkbench/ast/Block.java b/src/main/java/org/nittalab/rdlworkbench/ast/Block.java
new file mode 100644
index 0000000..45fa80c
--- /dev/null
+++ b/src/main/java/org/nittalab/rdlworkbench/ast/Block.java
@@ -0,0 +1,107 @@
+package org.nittalab.rdlworkbench.ast;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class Block extends Statement {
+ private List statements = new ArrayList<>();
+
+ public List getStatements2() {
+ return statements;
+ }
+
+ public void setStatements(List statements) {
+ this.statements = statements;
+ }
+
+ public void addFirstStatement(Statement statement) {
+ statements.add(0, statement);
+ }
+
+ public void addStatement(Statement statement) {
+ statements.add(statement);
+ }
+
+ public void addFirstStatements(List statements) {
+ this.statements.addAll(0, statements);
+ }
+
+ public void addStatements(List statements) {
+ this.statements.addAll(statements);
+ }
+
+ public boolean contains(List statements) {
+ if (statements.size() == 0) return true;
+ for (int i = 0; i < this.statements.size(); i++) {
+ Statement st = this.statements.get(i);
+ if (st.equals(statements.get(0))) {
+ if (statements.size() == 1) return true;
+ int j = 1;
+ for (int k = i + 1; k < this.statements.size(); k++) {
+ Statement st2 = this.statements.get(k);
+ if (st2.equals(statements.get(j))) {
+ j++;
+ if (j == statements.size()) return true;
+ }
+ }
+ }
+ }
+ return false;
+ }
+
+ //====================================================
+ //TODO: CodeGenerator修正後削除
+
+ public List getStatements() {
+ List strings = new ArrayList<>();
+ for (Statement stmt : statements) {
+ if (stmt != null) {
+ strings.add(stmt.toString());
+ }
+ }
+ return strings;
+ }
+
+ public void addFirstStatement(String statement) {
+ if (statement != null) {
+ this.addFirstStatement(new Statement() {
+ @Override
+ public String toString() {
+ return statement;
+ }
+ });
+ }
+ }
+
+ public void addStatement(String statement) {
+ if (statement != null) {
+ this.addStatement(new PlainStatement(statement));
+ }
+ }
+
+ //====================================================
+
+
+ @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/src/main/java/org/nittalab/rdlworkbench/ast/BodyDeclaration.java b/src/main/java/org/nittalab/rdlworkbench/ast/BodyDeclaration.java
new file mode 100644
index 0000000..078a1e3
--- /dev/null
+++ b/src/main/java/org/nittalab/rdlworkbench/ast/BodyDeclaration.java
@@ -0,0 +1,13 @@
+package org.nittalab.rdlworkbench.ast;
+
+public abstract class BodyDeclaration extends ASTNode {
+ private int modifiers = 0;
+
+ public int getModifiers() {
+ return modifiers;
+ }
+
+ public void setModifiers(int modifiers) {
+ this.modifiers = modifiers;
+ }
+}
diff --git a/src/main/java/org/nittalab/rdlworkbench/ast/ClassInstanceCreation.java b/src/main/java/org/nittalab/rdlworkbench/ast/ClassInstanceCreation.java
new file mode 100644
index 0000000..6dc8ff0
--- /dev/null
+++ b/src/main/java/org/nittalab/rdlworkbench/ast/ClassInstanceCreation.java
@@ -0,0 +1,71 @@
+package org.nittalab.rdlworkbench.ast;
+
+import java.util.ArrayList;
+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;
+ }
+
+ @Override
+ public Expression replace(Variable variable, Expression expression) {
+ List replacedExpressions = new ArrayList<>();
+
+ for (Expression argument : arguments) {
+ replacedExpressions.add(argument.replace(variable, expression));
+ }
+
+ return new ClassInstanceCreation(type, replacedExpressions);
+ }
+
+ 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/src/main/java/org/nittalab/rdlworkbench/ast/CodeUtil.java b/src/main/java/org/nittalab/rdlworkbench/ast/CodeUtil.java
new file mode 100644
index 0000000..0960970
--- /dev/null
+++ b/src/main/java/org/nittalab/rdlworkbench/ast/CodeUtil.java
@@ -0,0 +1,13 @@
+package org.nittalab.rdlworkbench.ast;
+
+public class CodeUtil {
+
+ public static String insertTab(String code) {
+ String newString = "";
+ String[] lines = code.split("\n");
+ for (String line: lines) {
+ newString = newString + "\t" + line + "\n";
+ }
+ return newString;
+ }
+}
diff --git a/src/main/java/org/nittalab/rdlworkbench/ast/CompilationUnit.java b/src/main/java/org/nittalab/rdlworkbench/ast/CompilationUnit.java
new file mode 100644
index 0000000..9cdfe74
--- /dev/null
+++ b/src/main/java/org/nittalab/rdlworkbench/ast/CompilationUnit.java
@@ -0,0 +1,67 @@
+package org.nittalab.rdlworkbench.ast;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class CompilationUnit extends ASTNode {
+ private String fileName = null;
+ private List imports = new ArrayList<>();
+ private List types = new ArrayList<>();
+ private List interfaces = new ArrayList<>();
+
+ public CompilationUnit(TypeDeclaration type) {
+ types.add(type);
+ if(type.getTypeName().contains("<"))
+ fileName = type.getTypeName().split("<")[0] + ".java";
+ else
+ fileName = type.getTypeName() + ".java";
+ }
+
+ public CompilationUnit(InterfaceDeclaration interfaceDeclaration) {
+ interfaces.add(interfaceDeclaration);
+ fileName = interfaceDeclaration.getTypeName() + ".java";
+ }
+
+ public List imports() {
+ return imports;
+ }
+
+ public List types() {
+ return types;
+ }
+
+ public void addImport(ImportDeclaration imp) {
+ imports.add(imp);
+ }
+
+ public void addType(TypeDeclaration type) {
+ types.add(type);
+ }
+
+ public List interfaces() {
+ return interfaces;
+ }
+
+ public void addInterface(InterfaceDeclaration interfaceDeclaration) {
+ interfaces.add(interfaceDeclaration);
+ }
+
+ public String getFileName() {
+ return fileName;
+ }
+
+ public String toString() {
+ String result = "";
+ for (ImportDeclaration imp: imports) {
+ result += imp.toString();
+ }
+ result +="\n";
+ for (TypeDeclaration type: types) {
+ result += type.toString();
+ }
+ for (InterfaceDeclaration iDec: interfaces) {
+ result += iDec.toString();
+ }
+ return result;
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/org/nittalab/rdlworkbench/ast/Constant.java b/src/main/java/org/nittalab/rdlworkbench/ast/Constant.java
new file mode 100644
index 0000000..d441be0
--- /dev/null
+++ b/src/main/java/org/nittalab/rdlworkbench/ast/Constant.java
@@ -0,0 +1,32 @@
+package org.nittalab.rdlworkbench.ast;
+
+/**
+ * Represents a constant in the AST (Abstract Syntax Tree)
+ *
+ * @author s-yamagiwa
+ */
+public class Constant extends Expression {
+ private String value;
+
+ public Constant(String value) {
+ this.value = value;
+ }
+
+ @Override
+ public Expression replace(Variable variable, Expression expression) {
+ return this;
+ }
+
+ public String getValue() {
+ return value;
+ }
+
+ public void setValue(String value) {
+ this.value = value;
+ }
+
+ @Override
+ public String toString() {
+ return value;
+ }
+}
diff --git a/src/main/java/org/nittalab/rdlworkbench/ast/EnhancedForStatement.java b/src/main/java/org/nittalab/rdlworkbench/ast/EnhancedForStatement.java
new file mode 100644
index 0000000..e4da98f
--- /dev/null
+++ b/src/main/java/org/nittalab/rdlworkbench/ast/EnhancedForStatement.java
@@ -0,0 +1,23 @@
+package org.nittalab.rdlworkbench.ast;
+
+public class EnhancedForStatement extends Statement {
+
+ private VariableDeclaration singleVariableDeclaration;
+ private Expression expression;
+ private Statement body;
+
+ public VariableDeclaration getParameter() { return singleVariableDeclaration; }
+ public void setParameter(VariableDeclaration parameter) { this.singleVariableDeclaration = parameter; }
+
+ public Expression getExpression() { return expression; }
+ public void setExpression(Expression expression) { this.expression = expression; }
+
+ public Statement getBody() { return body; }
+ public void setBody(Statement body) { this.body = body; }
+
+ @Override
+ public String toString() {
+ String typeName = singleVariableDeclaration.getType().getImplementationTypeName();
+ return "for (" + typeName + " " + singleVariableDeclaration.getName() + " : " + expression + ") " + body;
+ }
+}
diff --git a/src/main/java/org/nittalab/rdlworkbench/ast/Expression.java b/src/main/java/org/nittalab/rdlworkbench/ast/Expression.java
new file mode 100644
index 0000000..5fbb9ec
--- /dev/null
+++ b/src/main/java/org/nittalab/rdlworkbench/ast/Expression.java
@@ -0,0 +1,19 @@
+package org.nittalab.rdlworkbench.ast;
+
+/**
+ * Abstract base class for all expression nodes in the abstract syntax tree (AST).
+ *
+ * @author s-yamagiwa
+ */
+public abstract class Expression extends ASTNode {
+ /**
+ * Replace {@code variable} with {@code expression} in AST.
+ *
+ * @param variable The variable to be replaced
+ * @param expression The expression that {@code variable} is replaced to
+ * @return A duplicated expression that is replaced with a given {@code expression}
+ * @implNote The instance of any member must be immutable
+ * @apiNote All variables match to the given one will be replaced with the given {@code expression}
+ */
+ public abstract Expression replace(Variable variable, Expression expression);
+}
diff --git a/src/main/java/org/nittalab/rdlworkbench/ast/ExpressionStatement.java b/src/main/java/org/nittalab/rdlworkbench/ast/ExpressionStatement.java
new file mode 100644
index 0000000..a0e65fe
--- /dev/null
+++ b/src/main/java/org/nittalab/rdlworkbench/ast/ExpressionStatement.java
@@ -0,0 +1,17 @@
+package org.nittalab.rdlworkbench.ast;
+
+public class ExpressionStatement extends Statement{
+ private Expression expression;
+
+ public ExpressionStatement(Expression expression) {
+ this.expression = expression;
+ }
+
+ public Expression getExpression() { return expression; }
+ public void setExpression(Expression expression) { this.expression = expression; }
+
+ @Override
+ public String toString() {
+ return expression + ";";
+ }
+}
diff --git a/src/main/java/org/nittalab/rdlworkbench/ast/FieldAccess.java b/src/main/java/org/nittalab/rdlworkbench/ast/FieldAccess.java
new file mode 100644
index 0000000..187af27
--- /dev/null
+++ b/src/main/java/org/nittalab/rdlworkbench/ast/FieldAccess.java
@@ -0,0 +1,50 @@
+package org.nittalab.rdlworkbench.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;
+ }
+
+ @Override
+ public Expression replace(Variable variable, Expression expression) {
+ return new FieldAccess(expression.replace(variable, expression), 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/src/main/java/org/nittalab/rdlworkbench/ast/FieldDeclaration.java b/src/main/java/org/nittalab/rdlworkbench/ast/FieldDeclaration.java
new file mode 100644
index 0000000..b38af0d
--- /dev/null
+++ b/src/main/java/org/nittalab/rdlworkbench/ast/FieldDeclaration.java
@@ -0,0 +1,90 @@
+package org.nittalab.rdlworkbench.ast;
+
+import models.algebra.Type;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+
+public class FieldDeclaration extends BodyDeclaration implements IAnnotatable {
+ private Type type;
+ private String fieldName;
+ private String initializer = null;
+ private String initializationBlock = null;
+ private Map annotations = new HashMap<>();
+
+ public FieldDeclaration(Type type, String fieldName) {
+ this.type = type;
+ this.fieldName = fieldName;
+ }
+
+ public FieldDeclaration(Type type, String fieldName, String initializer) {
+ this.type = type;
+ this.fieldName = fieldName;
+ this.initializer = initializer;
+ }
+
+ public Type getType() {
+ return type;
+ }
+
+ public void setType(Type type) {
+ this.type = type;
+ }
+
+ public String getName() {
+ return fieldName;
+ }
+
+ public void setName(String fieldName) {
+ this.fieldName = fieldName;
+ }
+
+ public String getInitializer() {
+ return initializer;
+ }
+
+ public void setInitializer(String initializer) {
+ this.initializer = initializer;
+ }
+
+ public String getInitializationBlock() {
+ return initializationBlock;
+ }
+
+ public void setInitializationBlock(String initializationBlock) {
+ this.initializationBlock = initializationBlock;
+ }
+
+ @Override
+ public Annotation getAnnotation(String name) {
+ return annotations.get(name);
+ }
+
+ @Override
+ public Collection getAnnotations() {
+ return annotations.values();
+ }
+
+ @Override
+ public void addAnnotation(Annotation annotation) {
+ annotations.put(annotation.getElementName(), annotation);
+ }
+
+ public String toString() {
+ String code = "";
+ for (Annotation annotation: getAnnotations()) {
+ code += annotation.toString() + "\n";
+ }
+ if (initializationBlock != null) {
+ code += "private " + type.getInterfaceTypeName() + " " + fieldName + ";\n" + initializationBlock + "\n";
+ } else {
+ if (initializer == null) {
+ code += "private " + type.getInterfaceTypeName() + " " + fieldName + ";\n";
+ } else {
+ code += "private " + type.getInterfaceTypeName() + " " + fieldName + " = " + initializer + ";\n";
+ }
+ }
+ return code;
+ }
+}
diff --git a/src/main/java/org/nittalab/rdlworkbench/ast/ForStatement.java b/src/main/java/org/nittalab/rdlworkbench/ast/ForStatement.java
new file mode 100644
index 0000000..f7defd5
--- /dev/null
+++ b/src/main/java/org/nittalab/rdlworkbench/ast/ForStatement.java
@@ -0,0 +1,70 @@
+package org.nittalab.rdlworkbench.ast;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class ForStatement extends Statement {
+
+ private List initializers = new ArrayList<>();
+ private Expression optionalConditionExpression;
+ private List updaters = new ArrayList<>();
+ private Statement body;
+
+ public List getInitializers() {
+ return initializers;
+ }
+
+ public void setInitializers(List initializers) {
+ this.initializers = initializers;
+ }
+
+ public Expression getExpression() {
+ return optionalConditionExpression;
+ }
+
+ public void setExpression(Expression expression) {
+ this.optionalConditionExpression = expression;
+ }
+
+ 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++) {
+ String init = initializers.get(i).toString();
+ sb.append(init.endsWith(";") ? init.substring(0, init.length() - 1) : init);
+ if (i < initializers.size() - 1) sb.append(", ");
+ }
+ sb.append("; ");
+
+ if (optionalConditionExpression != null) sb.append(optionalConditionExpression);
+ sb.append("; ");
+
+ for (int i = 0; i < updaters.size(); i++) {
+ String update = updaters.get(i).toString();
+ sb.append(update.endsWith(";") ? update.substring(0, update.length() - 1) : update);
+ 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/src/main/java/org/nittalab/rdlworkbench/ast/IAnnotatable.java b/src/main/java/org/nittalab/rdlworkbench/ast/IAnnotatable.java
new file mode 100644
index 0000000..5a2c86a
--- /dev/null
+++ b/src/main/java/org/nittalab/rdlworkbench/ast/IAnnotatable.java
@@ -0,0 +1,9 @@
+package org.nittalab.rdlworkbench.ast;
+
+import java.util.Collection;
+
+public interface IAnnotatable {
+ Annotation getAnnotation(String name);
+ Collection getAnnotations();
+ void addAnnotation(Annotation annotation);
+}
diff --git a/src/main/java/org/nittalab/rdlworkbench/ast/IfStatement.java b/src/main/java/org/nittalab/rdlworkbench/ast/IfStatement.java
new file mode 100644
index 0000000..1239698
--- /dev/null
+++ b/src/main/java/org/nittalab/rdlworkbench/ast/IfStatement.java
@@ -0,0 +1,43 @@
+package org.nittalab.rdlworkbench.ast;
+
+public class IfStatement extends Statement {
+
+ private Expression expression;
+ private Statement thenStatement;
+ private Statement elseStatement;
+
+ public Expression getExpression() {
+ return expression;
+ }
+
+ public void setExpression(Expression 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);
+ sb.append(thenStatement);
+ if (elseStatement != null) {
+ sb.append(" else ").append(elseStatement);
+ }
+ return sb.toString();
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/org/nittalab/rdlworkbench/ast/ImportDeclaration.java b/src/main/java/org/nittalab/rdlworkbench/ast/ImportDeclaration.java
new file mode 100644
index 0000000..8d65586
--- /dev/null
+++ b/src/main/java/org/nittalab/rdlworkbench/ast/ImportDeclaration.java
@@ -0,0 +1,21 @@
+package org.nittalab.rdlworkbench.ast;
+
+public class ImportDeclaration {
+ private String name;
+
+ public ImportDeclaration(String name) {
+ this.name = name;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String toString() {
+ return "import " + name + ";\n";
+ }
+}
diff --git a/src/main/java/org/nittalab/rdlworkbench/ast/InfixExpression.java b/src/main/java/org/nittalab/rdlworkbench/ast/InfixExpression.java
new file mode 100644
index 0000000..a05f753
--- /dev/null
+++ b/src/main/java/org/nittalab/rdlworkbench/ast/InfixExpression.java
@@ -0,0 +1,55 @@
+package org.nittalab.rdlworkbench.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;
+ }
+
+ @Override
+ public Expression replace(Variable variable, Expression expression) {
+ return new InfixExpression(operator, leftOperand.replace(variable, expression), rightOperand.replace(variable, expression));
+ }
+
+ 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/src/main/java/org/nittalab/rdlworkbench/ast/InterfaceDeclaration.java b/src/main/java/org/nittalab/rdlworkbench/ast/InterfaceDeclaration.java
new file mode 100644
index 0000000..377699d
--- /dev/null
+++ b/src/main/java/org/nittalab/rdlworkbench/ast/InterfaceDeclaration.java
@@ -0,0 +1,67 @@
+package org.nittalab.rdlworkbench.ast;
+
+import java.util.*;
+
+
+public class InterfaceDeclaration extends AbstractTypeDeclaration implements IAnnotatable {
+ private List methods = new ArrayList<>();
+ private Map annotations = new HashMap<>();
+
+ public InterfaceDeclaration(String typeName) {
+ this.typeName = typeName;
+ }
+
+ public void addMethod(MethodDeclaration method) {
+ methods.add(method);
+ }
+
+ public void removeMethod(MethodDeclaration method) {
+ methods.remove(method);
+ }
+
+ public List getMethods() {
+ return methods;
+ }
+
+ @Override
+ public Annotation getAnnotation(String name) {
+ return annotations.get(name);
+ }
+
+ @Override
+ public Collection getAnnotations() {
+ return annotations.values();
+ }
+
+ @Override
+ public void addAnnotation(Annotation annotation) {
+ annotations.put(annotation.getElementName(), annotation);
+ }
+
+ public String toString() {
+ String code = "";
+ for (Annotation annotation : getAnnotations()) {
+ code += annotation.toString() + "\n";
+ }
+ code += "public interface " + typeName + " {\n";
+ for (MethodDeclaration m : methods) {
+ String signature = "\t";
+ if (m.getReturnType() == null) {
+ signature += "void ";
+ } else {
+ signature += m.getReturnType().getInterfaceTypeName() + " ";
+ }
+ signature += m.getName() + "(";
+ if (m.getParameters() != null) {
+ for (int i = 0; i < m.getParameters().size(); i++) {
+ signature += m.getParameters().get(i).toString();
+ if (i < m.getParameters().size() - 1) signature += ", ";
+ }
+ }
+ signature += ");\n";
+ code += signature;
+ }
+ code += "}";
+ return code;
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/org/nittalab/rdlworkbench/ast/Lexer.java b/src/main/java/org/nittalab/rdlworkbench/ast/Lexer.java
new file mode 100644
index 0000000..ed3510e
--- /dev/null
+++ b/src/main/java/org/nittalab/rdlworkbench/ast/Lexer.java
@@ -0,0 +1,55 @@
+package org.nittalab.rdlworkbench.ast;
+
+/**
+ * The Lexer class provides functionalities for parsing and iterating through
+ * a source string of text character by character.
+ *
+ * @author s-yamagiwa;
+ */
+public class Lexer {
+ private final String source;
+ private int position;
+
+ public Lexer(String source) {
+ this.source = source;
+ this.position = 0;
+ }
+
+ /**
+ * Retrieves the next character without advancing the position.
+ *
+ * @return The next character.
+ */
+ public char peek() {
+ if (position >= source.length()) {
+ return '\0'; // End of line
+ }
+
+ return source.charAt(position);
+ }
+
+ /**
+ * Retrieves the next character after advancing the position.
+ *
+ * @return The next character.
+ */
+ public char peekNext() {
+ if (position + 1 >= source.length()) {
+ return '\0'; // End of line
+ }
+
+ return source.charAt(position + 1);
+ }
+
+ /**
+ * Advances the position by one character.
+ *
+ * @return The character that was previously at the current position.
+ */
+ public char advance() {
+ char current = peek();
+ position++;
+
+ return current;
+ }
+}
diff --git a/src/main/java/org/nittalab/rdlworkbench/ast/MethodDeclaration.java b/src/main/java/org/nittalab/rdlworkbench/ast/MethodDeclaration.java
new file mode 100644
index 0000000..47e7ec8
--- /dev/null
+++ b/src/main/java/org/nittalab/rdlworkbench/ast/MethodDeclaration.java
@@ -0,0 +1,190 @@
+package org.nittalab.rdlworkbench.ast;
+
+import java.util.*;
+
+public class MethodDeclaration extends BodyDeclaration implements IAnnotatable {
+ private String name = null;
+ private boolean isConstructor = false;
+ private Type returnType = null;
+ private List parameters = null;
+ private Block body = null;
+ private Map annotations = new HashMap<>();
+ private Throws thrws = null;
+
+ public MethodDeclaration(String methodName) {
+ this(methodName, false);
+ }
+
+ public MethodDeclaration(String methodName, Type returnType) {
+ this(methodName, false);
+ this.returnType = returnType;
+ }
+
+ public MethodDeclaration(String methodName, boolean isConstructor) {
+ this.name = methodName;
+ this.isConstructor = isConstructor;
+ }
+
+ public MethodDeclaration(String methodName, boolean isConstructor, Type returnType, List parameters) {
+ this(methodName, isConstructor, returnType, parameters, null);
+ }
+
+ public MethodDeclaration(String methodName, boolean isConstructor, Type returnType, List parameters, Block body) {
+ this(methodName, isConstructor);
+ this.returnType = returnType;
+ this.parameters = parameters;
+ this.body = body;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public boolean isConstructor() {
+ return isConstructor;
+ }
+
+ public void setConstructor(boolean isConstructor) {
+ this.isConstructor = isConstructor;
+ }
+
+ public Type getReturnType() {
+ return returnType;
+ }
+
+ public void setReturnType(Type returnType) {
+ this.returnType = returnType;
+ }
+
+ public List getParameters() {
+ return parameters;
+ }
+
+ public void setParameters(List parameters) {
+ this.parameters = parameters;
+ }
+
+ public void addParameter(VariableDeclaration parameter) {
+ if (parameters == null) {
+ parameters = new ArrayList<>();
+ }
+ parameters.add(parameter);
+ }
+
+ public Block getBody() {
+ if (body == null) {
+ body = new Block();
+ }
+ return body;
+ }
+
+ public void setBody(Block body) {
+ this.body = body;
+ }
+
+ public void addUniqueStatement(Statement statement) {
+ if (body == null) {
+ body = new Block();
+ body.addStatement(statement);
+ return;
+ }
+ if (body.contains(List.of(statement))) return;
+ body.addStatement(statement);
+ }
+
+ public void addStatement(Statement statement) {
+ if (body == null) {
+ body = new Block();
+ }
+ body.addStatement(statement);
+ }
+
+ public void addUniqueStatement(String statement) {
+ if (body == null) {
+ body = new Block();
+ body.addStatement(statement);
+ return;
+ }
+ if (body.contains(List.of(new PlainStatement(statement)))) return;
+ body.addStatement(statement);
+ }
+
+ public void addStatement(String statement) {
+ if (body == null) {
+ body = new Block();
+ }
+ body.addStatement(statement);
+ }
+
+ public void addFirstStatement(Statement statement) {
+ if (body == null) {
+ body = new Block();
+ }
+ body.addFirstStatement(statement);
+ }
+
+ public void addFirstStatement(String statement) {
+ if (body == null) {
+ body = new Block();
+ }
+ body.addFirstStatement(statement);
+ }
+
+ public void addThrow(String exception) {
+ if (thrws == null) {
+ thrws = new Throws();
+ }
+ thrws.addException(exception);
+ }
+
+ public Throws getThrows() {
+ return thrws;
+ }
+
+ @Override
+ public Annotation getAnnotation(String name) {
+ return annotations.get(name);
+ }
+
+ @Override
+ public Collection getAnnotations() {
+ return annotations.values();
+ }
+
+ @Override
+ public void addAnnotation(Annotation annotation) {
+ annotations.put(annotation.getElementName(), annotation);
+ }
+
+ public String toString() {
+ String code = "";
+ for (Annotation annotation: getAnnotations()) {
+ code += annotation.toString() + "\n";
+ }
+ code += "public ";
+ if (returnType == null) {
+ if(!isConstructor) code += "void ";
+ }else {
+ code += returnType.toString() + " ";
+ }
+ code += (name + "(");
+ if (parameters != null) {
+ for (int i = 0; i < parameters.size(); i++) {
+ code += parameters.get(i).toString();
+ if (i < parameters.size() - 1) code += ", ";
+ }
+ }
+ code += ") ";
+
+ if (body != null) {
+ code += body.toString();
+ } else {
+ code += ";";
+ }
+ return code;
+ }
+}
diff --git a/src/main/java/org/nittalab/rdlworkbench/ast/MethodInvocation.java b/src/main/java/org/nittalab/rdlworkbench/ast/MethodInvocation.java
new file mode 100644
index 0000000..6058303
--- /dev/null
+++ b/src/main/java/org/nittalab/rdlworkbench/ast/MethodInvocation.java
@@ -0,0 +1,107 @@
+package org.nittalab.rdlworkbench.ast;
+
+import java.util.ArrayList;
+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;
+ }
+
+ @Override
+ public Expression replace(Variable variable, Expression expression) {
+ List replacedExpressions = new ArrayList<>();
+
+ for (Expression argument : arguments) {
+ replacedExpressions.add(argument.replace(variable, expression));
+ }
+
+ if (receiver == null) {
+ return new MethodInvocation(null, methodName, replacedExpressions);
+ }
+
+ return new MethodInvocation(receiver.replace(variable, expression), methodName, replacedExpressions);
+ }
+
+ 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() {
+ StringBuilder builder = new StringBuilder();
+ if (receiver != null) {
+ builder.append(receiver.toString()).append(".");
+ }
+
+ builder.append(methodName).append("(");
+
+ if (arguments != null && !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/src/main/java/org/nittalab/rdlworkbench/ast/Modifier.java b/src/main/java/org/nittalab/rdlworkbench/ast/Modifier.java
new file mode 100644
index 0000000..6d47367
--- /dev/null
+++ b/src/main/java/org/nittalab/rdlworkbench/ast/Modifier.java
@@ -0,0 +1,29 @@
+package org.nittalab.rdlworkbench.ast;
+
+public class Modifier extends ASTNode {
+ public static final int ABSTRACT = 0x0400;
+ public static final int PRIVATE = 0x0002;
+ public static final int PROTECTED = 0x0004;
+ public static final int PUBLIC = 0x0001;
+ public static final int STATIC = 0x0008;
+
+ public static boolean isAbstract(int flags) {
+ return (flags & ABSTRACT) != 0;
+ }
+
+ public static boolean isPrivate(int flags) {
+ return (flags & PRIVATE) != 0;
+ }
+
+ public static boolean isProtected(int flags) {
+ return (flags & PROTECTED) != 0;
+ }
+
+ public static boolean isPublic(int flags) {
+ return (flags & PUBLIC) != 0;
+ }
+
+ public static boolean isStatic(int flags) {
+ return (flags & STATIC) != 0;
+ }
+}
diff --git a/src/main/java/org/nittalab/rdlworkbench/ast/ParameterizedType.java b/src/main/java/org/nittalab/rdlworkbench/ast/ParameterizedType.java
new file mode 100644
index 0000000..93a1c28
--- /dev/null
+++ b/src/main/java/org/nittalab/rdlworkbench/ast/ParameterizedType.java
@@ -0,0 +1,109 @@
+package org.nittalab.rdlworkbench.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;
+ }
+
+
+ /**
+ * Replace all type arguments and their descendant types that match the replacedType with the replacingType.
+ * @param replacedType the type to be replaced
+ * @param replacingType the type to replace with
+ */
+ public void replaceSubTypes(Type replacedType, Type replacingType) {
+ for (int i = 0; i < typeArguments.size(); i++) {
+ Type typeArgment = typeArguments.get(i);
+ if (typeArgment.equals(replacedType)) {
+ typeArguments.set(i, replacingType);
+ } else if (typeArgment instanceof ParameterizedType) {
+ ((ParameterizedType) typeArgment).replaceSubTypes(replacedType, replacingType);
+ }
+ }
+ }
+
+ @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/src/main/java/org/nittalab/rdlworkbench/ast/ParenthesizedExpression.java b/src/main/java/org/nittalab/rdlworkbench/ast/ParenthesizedExpression.java
new file mode 100644
index 0000000..3a18824
--- /dev/null
+++ b/src/main/java/org/nittalab/rdlworkbench/ast/ParenthesizedExpression.java
@@ -0,0 +1,33 @@
+package org.nittalab.rdlworkbench.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;
+ }
+
+ @Override
+ public Expression replace(Variable variable, Expression expression) {
+ return new ParenthesizedExpression(this.expression.replace(variable, expression));
+ }
+
+ public Expression getExpression() {
+ return expression;
+ }
+
+ public void setExpression(Expression expression) {
+ this.expression = expression;
+ }
+
+ @Override
+ public String toString() {
+ return "(" + expression.toString() + ")";
+ }
+}
diff --git a/src/main/java/org/nittalab/rdlworkbench/ast/PlainExpression.java b/src/main/java/org/nittalab/rdlworkbench/ast/PlainExpression.java
new file mode 100644
index 0000000..2215e98
--- /dev/null
+++ b/src/main/java/org/nittalab/rdlworkbench/ast/PlainExpression.java
@@ -0,0 +1,23 @@
+package org.nittalab.rdlworkbench.ast;
+
+//====================================================
+//TODO: CodeGenerator修正後削除
+//====================================================
+
+public class PlainExpression extends Expression {
+ private String expression;
+
+ public PlainExpression(String expression) {
+ this.expression = expression;
+ }
+
+ @Override
+ public Expression replace(Variable variable, Expression newExpression) {
+ return new PlainExpression(expression.replace(variable.toString(), newExpression.toString()));
+ }
+
+ @Override
+ public String toString() {
+ return expression;
+ }
+}
diff --git a/src/main/java/org/nittalab/rdlworkbench/ast/PlainStatement.java b/src/main/java/org/nittalab/rdlworkbench/ast/PlainStatement.java
new file mode 100644
index 0000000..c197353
--- /dev/null
+++ b/src/main/java/org/nittalab/rdlworkbench/ast/PlainStatement.java
@@ -0,0 +1,18 @@
+package org.nittalab.rdlworkbench.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/src/main/java/org/nittalab/rdlworkbench/ast/PostfixExpression.java b/src/main/java/org/nittalab/rdlworkbench/ast/PostfixExpression.java
new file mode 100644
index 0000000..ff86184
--- /dev/null
+++ b/src/main/java/org/nittalab/rdlworkbench/ast/PostfixExpression.java
@@ -0,0 +1,58 @@
+package org.nittalab.rdlworkbench.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;
+ }
+
+ @Override
+ public Expression replace(Variable variable, Expression expression) {
+ return new PostfixExpression(operand.replace(variable, expression), 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/src/main/java/org/nittalab/rdlworkbench/ast/PrefixExpression.java b/src/main/java/org/nittalab/rdlworkbench/ast/PrefixExpression.java
new file mode 100644
index 0000000..16b3adf
--- /dev/null
+++ b/src/main/java/org/nittalab/rdlworkbench/ast/PrefixExpression.java
@@ -0,0 +1,58 @@
+package org.nittalab.rdlworkbench.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;
+ }
+
+ @Override
+ public Expression replace(Variable variable, Expression expression) {
+ return new PrefixExpression(operand.replace(variable, expression), 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/src/main/java/org/nittalab/rdlworkbench/ast/PrimitiveType.java b/src/main/java/org/nittalab/rdlworkbench/ast/PrimitiveType.java
new file mode 100644
index 0000000..00fbb23
--- /dev/null
+++ b/src/main/java/org/nittalab/rdlworkbench/ast/PrimitiveType.java
@@ -0,0 +1,34 @@
+package org.nittalab.rdlworkbench.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 String typeName;
+
+ public PrimitiveType(String typeName) {
+ this.typeName = typeName;
+ }
+
+ @Override
+ public String toString() {
+ if (getAnnotations().isEmpty()) {
+ return typeName;
+ }
+
+ StringBuilder builder = new StringBuilder();
+ for (Annotation annotation : getAnnotations()) {
+ builder.append(annotation.toString());
+ builder.append(" ");
+ }
+ builder.append(typeName);
+
+ return builder.toString();
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/org/nittalab/rdlworkbench/ast/ReturnStatement.java b/src/main/java/org/nittalab/rdlworkbench/ast/ReturnStatement.java
new file mode 100644
index 0000000..964900e
--- /dev/null
+++ b/src/main/java/org/nittalab/rdlworkbench/ast/ReturnStatement.java
@@ -0,0 +1,21 @@
+package org.nittalab.rdlworkbench.ast;
+
+public class ReturnStatement extends Statement{
+ private Expression expression;
+
+ public Expression getExpression() {
+ return expression;
+ }
+
+ public void setExpression(Expression expression) {
+ this.expression = expression;
+ }
+
+ @Override
+ public String toString() {
+ if (expression != null) {
+ return "return " + expression + ";";
+ }
+ return "return;";
+ }
+}
diff --git a/src/main/java/org/nittalab/rdlworkbench/ast/SimpleType.java b/src/main/java/org/nittalab/rdlworkbench/ast/SimpleType.java
new file mode 100644
index 0000000..c3f3d76
--- /dev/null
+++ b/src/main/java/org/nittalab/rdlworkbench/ast/SimpleType.java
@@ -0,0 +1,39 @@
+package org.nittalab.rdlworkbench.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 String name;
+
+ public SimpleType(String name) {
+ this.name = name;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ @Override
+ public String toString() {
+ if (getAnnotations().isEmpty()) {
+ return name;
+ }
+
+ StringBuilder builder = new StringBuilder();
+ for (Annotation annotation : getAnnotations()) {
+ builder.append(annotation.toString());
+ builder.append(" ");
+ }
+ builder.append(name);
+
+ return builder.toString();
+ }
+}
diff --git a/src/main/java/org/nittalab/rdlworkbench/ast/Statement.java b/src/main/java/org/nittalab/rdlworkbench/ast/Statement.java
new file mode 100644
index 0000000..8b18777
--- /dev/null
+++ b/src/main/java/org/nittalab/rdlworkbench/ast/Statement.java
@@ -0,0 +1,15 @@
+package org.nittalab.rdlworkbench.ast;
+
+public abstract class Statement extends ASTNode {
+
+ @Override
+ public abstract String toString();
+
+ @Override
+ public boolean equals(Object another) {
+ if (!(another instanceof Statement)) {
+ return false;
+ }
+ return toString().equals(another.toString());
+ }
+}
diff --git a/src/main/java/org/nittalab/rdlworkbench/ast/SuperMethodInvocation.java b/src/main/java/org/nittalab/rdlworkbench/ast/SuperMethodInvocation.java
new file mode 100644
index 0000000..b030d0c
--- /dev/null
+++ b/src/main/java/org/nittalab/rdlworkbench/ast/SuperMethodInvocation.java
@@ -0,0 +1,74 @@
+package org.nittalab.rdlworkbench.ast;
+
+import java.util.ArrayList;
+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;
+ }
+
+ @Override
+ public Expression replace(Variable variable, Expression expression) {
+ List replacedExpressions = new ArrayList<>();
+
+ for (Expression argument : arguments) {
+ replacedExpressions.add(argument.replace(variable, expression));
+ }
+
+ return new SuperMethodInvocation(methodName, replacedExpressions);
+ }
+
+ 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/src/main/java/org/nittalab/rdlworkbench/ast/ThisExpression.java b/src/main/java/org/nittalab/rdlworkbench/ast/ThisExpression.java
new file mode 100644
index 0000000..5de7ebf
--- /dev/null
+++ b/src/main/java/org/nittalab/rdlworkbench/ast/ThisExpression.java
@@ -0,0 +1,13 @@
+package org.nittalab.rdlworkbench.ast;
+
+public class ThisExpression extends Expression {
+ @Override
+ public Expression replace(Variable variable, Expression expression) {
+ return this;
+ }
+
+ @Override
+ public String toString() {
+ return "this";
+ }
+}
diff --git a/src/main/java/org/nittalab/rdlworkbench/ast/Throws.java b/src/main/java/org/nittalab/rdlworkbench/ast/Throws.java
new file mode 100644
index 0000000..2246851
--- /dev/null
+++ b/src/main/java/org/nittalab/rdlworkbench/ast/Throws.java
@@ -0,0 +1,29 @@
+package org.nittalab.rdlworkbench.ast;
+
+import java.util.HashSet;
+import java.util.Set;
+
+public class Throws extends ASTNode {
+ private Set exceptions = new HashSet<>();
+
+ public Throws() {
+ }
+
+ public void addException(String exception) {
+ exceptions.add(exception);
+ }
+
+ public Set getExceptions() {
+ return exceptions;
+ }
+
+ public String toString() {
+ String code = "throws ";
+ String delimiter = "";
+ for (String exception: exceptions) {
+ code += delimiter + exception;
+ delimiter = ", ";
+ }
+ return code;
+ }
+}
diff --git a/src/main/java/org/nittalab/rdlworkbench/ast/Type.java b/src/main/java/org/nittalab/rdlworkbench/ast/Type.java
new file mode 100644
index 0000000..5545c68
--- /dev/null
+++ b/src/main/java/org/nittalab/rdlworkbench/ast/Type.java
@@ -0,0 +1,37 @@
+package org.nittalab.rdlworkbench.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 implements models.algebra.Type.ITypeImpl {
+ /**
+ * 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);
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/org/nittalab/rdlworkbench/ast/TypeDeclaration.java b/src/main/java/org/nittalab/rdlworkbench/ast/TypeDeclaration.java
new file mode 100644
index 0000000..2e4a5ea
--- /dev/null
+++ b/src/main/java/org/nittalab/rdlworkbench/ast/TypeDeclaration.java
@@ -0,0 +1,98 @@
+package org.nittalab.rdlworkbench.ast;
+
+import java.util.*;
+
+public class TypeDeclaration extends AbstractTypeDeclaration implements IAnnotatable {
+ private List fields = new ArrayList<>();
+ private List methods = new ArrayList<>();
+ private Map annotations = new HashMap<>();
+ private List implementsInterfaces = new ArrayList<>();
+
+ public TypeDeclaration(String typeName) {
+ this.typeName = typeName;
+ }
+
+ public TypeDeclaration(String typeName, List fields) {
+ this.typeName = typeName;
+ this.fields = fields;
+ }
+
+ public TypeDeclaration(String typeName, List fields, List methods) {
+ this.typeName = typeName;
+ this.fields = fields;
+ this.methods = methods;
+ }
+
+ public void addImplementsInterface(String interfaceName) {
+ implementsInterfaces.add(interfaceName);
+ }
+
+ public List getImplementsInterfaces() {
+ return implementsInterfaces;
+ }
+
+ public void addField(FieldDeclaration field) {
+ fields.add(field);
+ }
+
+ public void addMethod(MethodDeclaration method) {
+ methods.add(method);
+ }
+
+ public void removeMethod(MethodDeclaration method) {
+ methods.remove(method);
+ }
+
+ public void removeField(FieldDeclaration field) {
+ fields.remove(field);
+ }
+
+ public List getFields() {
+ return fields;
+ }
+
+ public List getMethods() {
+ return methods;
+ }
+
+ public MethodDeclaration createConstructor() {
+ MethodDeclaration constructor = new MethodDeclaration(typeName, true);
+ addMethod(constructor);
+ return constructor;
+ }
+
+ @Override
+ public Annotation getAnnotation(String name) {
+ return annotations.get(name);
+ }
+
+ @Override
+ public Collection getAnnotations() {
+ return annotations.values();
+ }
+
+ @Override
+ public void addAnnotation(Annotation annotation) {
+ annotations.put(annotation.getElementName(), annotation);
+ }
+
+ public String toString() {
+ String code = "";
+ for (Annotation annotation: getAnnotations()) {
+ code += annotation.toString() + "\n";
+ }
+ code += "public class " + typeName;
+ if (!implementsInterfaces.isEmpty()) {
+ code += " implements " + String.join(", ", implementsInterfaces);
+ }
+ code += " {\n";
+ for (FieldDeclaration f: fields) {
+ code += "\t" + f.toString();
+ }
+ for (MethodDeclaration m: methods) {
+ code += CodeUtil.insertTab(m.toString());
+ }
+ code += "}";
+ return code;
+ }
+}
diff --git a/src/main/java/org/nittalab/rdlworkbench/ast/TypeLiteral.java b/src/main/java/org/nittalab/rdlworkbench/ast/TypeLiteral.java
new file mode 100644
index 0000000..5e3c59e
--- /dev/null
+++ b/src/main/java/org/nittalab/rdlworkbench/ast/TypeLiteral.java
@@ -0,0 +1,32 @@
+package org.nittalab.rdlworkbench.ast;
+
+/**
+ * Represents a type literal expression in the AST.
+ *
+ * @author s-yamagiwa
+ */
+public class TypeLiteral extends Expression {
+ private Type type;
+
+ public TypeLiteral(Type type) {
+ this.type = type;
+ }
+
+ @Override
+ public Expression replace(Variable variable, Expression expression) {
+ return this;
+ }
+
+ public Type getType() {
+ return type;
+ }
+
+ public void setType(Type type) {
+ this.type = type;
+ }
+
+ @Override
+ public String toString() {
+ return type.toString();
+ }
+}
diff --git a/src/main/java/org/nittalab/rdlworkbench/ast/Variable.java b/src/main/java/org/nittalab/rdlworkbench/ast/Variable.java
new file mode 100644
index 0000000..24767cb
--- /dev/null
+++ b/src/main/java/org/nittalab/rdlworkbench/ast/Variable.java
@@ -0,0 +1,35 @@
+package org.nittalab.rdlworkbench.ast;
+
+/**
+ * Represents a variable in the AST (Abstract Syntax Tree)
+ *
+ * @author s-yamagiwa
+ */
+public class Variable extends Expression {
+ private String name;
+
+ public Variable(String name) {
+ this.name = name;
+ }
+
+ @Override
+ public Expression replace(Variable variable, Expression expression) {
+ if (this == variable) {
+ return expression;
+ }
+ return this;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ @Override
+ public String toString() {
+ return name;
+ }
+}
diff --git a/src/main/java/org/nittalab/rdlworkbench/ast/VariableDeclaration.java b/src/main/java/org/nittalab/rdlworkbench/ast/VariableDeclaration.java
new file mode 100644
index 0000000..6aae27b
--- /dev/null
+++ b/src/main/java/org/nittalab/rdlworkbench/ast/VariableDeclaration.java
@@ -0,0 +1,68 @@
+package org.nittalab.rdlworkbench.ast;
+
+import models.algebra.Type;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+
+public class VariableDeclaration extends ASTNode implements IAnnotatable {
+ private Type type;
+ private String variableName;
+ private Expression optionalInitializer;
+ private Map annotations = new HashMap<>();
+
+ public VariableDeclaration(Type type, String variableName) {
+ this.type = type;
+ this.variableName = variableName;
+ }
+
+ public VariableDeclaration(Type type, String variableName, Expression initializer) {
+ this(type, variableName);
+ this.optionalInitializer = initializer;
+ }
+
+ public Type getType() {
+ return type;
+ }
+
+ public void setType(Type type) {
+ this.type = type;
+ }
+
+ public String getName() {
+ return variableName;
+ }
+
+ public void setName(String variableName) {
+ this.variableName = variableName;
+ }
+
+ public Expression getInitializer() { return optionalInitializer; }
+
+ public void setInitializer(Expression initializer) { this.optionalInitializer = initializer; }
+
+ @Override
+ public Annotation getAnnotation(String name) {
+ return annotations.get(name);
+ }
+
+ @Override
+ public Collection getAnnotations() {
+ return annotations.values();
+ }
+
+ @Override
+ public void addAnnotation(Annotation annotation) {
+ annotations.put(annotation.getElementName(), annotation);
+ }
+
+ public String toString() {
+ String code = "";
+ code += type.getInterfaceTypeName() + " " + variableName;
+ if (optionalInitializer != null) {
+ code += " = " + optionalInitializer;
+ }
+ return code;
+ }
+}
diff --git a/src/main/java/org/nittalab/rdlworkbench/ast/VariableDeclarationStatement.java b/src/main/java/org/nittalab/rdlworkbench/ast/VariableDeclarationStatement.java
new file mode 100644
index 0000000..cd1fb61
--- /dev/null
+++ b/src/main/java/org/nittalab/rdlworkbench/ast/VariableDeclarationStatement.java
@@ -0,0 +1,82 @@
+package org.nittalab.rdlworkbench.ast;
+
+import models.algebra.Type;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class VariableDeclarationStatement extends Statement {
+
+ private List modifiers = new ArrayList<>();
+ private Type type = null;
+ 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 addFragment(VariableDeclaration fragment) {
+ if (fragment == null) return;
+
+ if (this.type == null) {
+ this.type = fragment.getType();
+ this.fragments.add(fragment);
+ } else {
+ if (this.type.equals(fragment.getType())) {
+ this.fragments.add(fragment);
+ } else {
+ System.err.println("Type mismatch: " + fragment);
+ }
+ }
+ }
+
+ public void setFragments(List fragments) {
+ this.fragments = fragments;
+
+ if (fragments != null && !fragments.isEmpty()) {
+ this.type = fragments.get(0).getType();
+ } else {
+ this.type = null;
+ }
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+
+ for (Integer mod : modifiers) {
+ if (mod == Modifier.PRIVATE) sb.append("private ");
+ else if (mod == Modifier.PUBLIC) sb.append("public ");
+ else if (mod == Modifier.PROTECTED) sb.append("protected ");
+ else if (mod == Modifier.STATIC) sb.append("static ");
+ }
+
+ if (this.type != null) {
+ sb.append(this.type.getInterfaceTypeName()).append(" ");
+ }
+
+ for (int i = 0; i < fragments.size(); i++) {
+ sb.append(fragments.get(i).toString());
+ if (i < fragments.size() - 1) sb.append(", ");
+ }
+
+ sb.append(";");
+ return sb.toString();
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/org/nittalab/rdlworkbench/ast/WhileStatement.java b/src/main/java/org/nittalab/rdlworkbench/ast/WhileStatement.java
new file mode 100644
index 0000000..b16c5a5
--- /dev/null
+++ b/src/main/java/org/nittalab/rdlworkbench/ast/WhileStatement.java
@@ -0,0 +1,33 @@
+package org.nittalab.rdlworkbench.ast;
+
+public class WhileStatement extends Statement {
+
+ private Expression expression;
+ private Statement body;
+
+ public Expression getExpression() {
+ return expression;
+ }
+
+ public void setExpression(Expression 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