From 4b13ceadd16145ddd813c1ddcbcd3cb0231c14d0 Mon Sep 17 00:00:00 2001
From: Manolis Dermitzakis
Date: Tue, 24 Jun 2025 15:16:44 +0300
Subject: [PATCH 01/31] feat: (wip) ArcscriptTranspiler initial cmake project
---
Cpp/.gitignore | 3 +-
Cpp/CMakeLists.txt | 70 +++++
Cpp/cmake/ExternalAntlr4Cpp.cmake | 177 +++++++++++
Cpp/cmake/FindANTLR.cmake | 124 ++++++++
Cpp/cmake/antlr4-generator.cmake.in | 181 +++++++++++
Cpp/cmake/antlr4-runtime.cmake.in | 13 +
Cpp/src/ArcscriptErrorExceptions.h | 54 ++++
Cpp/src/ArcscriptErrorListener.cpp | 12 +
Cpp/src/ArcscriptErrorListener.h | 14 +
Cpp/src/ArcscriptExpression.cpp | 312 +++++++++++++++++++
Cpp/src/ArcscriptExpression.h | 81 +++++
Cpp/src/ArcscriptFunctions.cpp | 206 +++++++++++++
Cpp/src/ArcscriptFunctions.h | 40 +++
Cpp/src/ArcscriptHelpers.h | 109 +++++++
Cpp/src/ArcscriptOutputs.cpp | 79 +++++
Cpp/src/ArcscriptOutputs.h | 96 ++++++
Cpp/src/ArcscriptParserBase.cpp | 99 ++++++
Cpp/src/ArcscriptParserBase.h | 19 ++
Cpp/src/ArcscriptTranspiler.cpp | 172 +++++++++++
Cpp/src/ArcscriptTranspiler.h | 164 ++++++++++
Cpp/src/ArcscriptVisitor.cpp | 461 ++++++++++++++++++++++++++++
Cpp/src/ArcscriptVisitor.h | 52 ++++
22 files changed, 2537 insertions(+), 1 deletion(-)
create mode 100755 Cpp/CMakeLists.txt
create mode 100755 Cpp/cmake/ExternalAntlr4Cpp.cmake
create mode 100755 Cpp/cmake/FindANTLR.cmake
create mode 100755 Cpp/cmake/antlr4-generator.cmake.in
create mode 100755 Cpp/cmake/antlr4-runtime.cmake.in
create mode 100755 Cpp/src/ArcscriptErrorExceptions.h
create mode 100755 Cpp/src/ArcscriptErrorListener.cpp
create mode 100755 Cpp/src/ArcscriptErrorListener.h
create mode 100755 Cpp/src/ArcscriptExpression.cpp
create mode 100755 Cpp/src/ArcscriptExpression.h
create mode 100755 Cpp/src/ArcscriptFunctions.cpp
create mode 100755 Cpp/src/ArcscriptFunctions.h
create mode 100755 Cpp/src/ArcscriptHelpers.h
create mode 100755 Cpp/src/ArcscriptOutputs.cpp
create mode 100755 Cpp/src/ArcscriptOutputs.h
create mode 100755 Cpp/src/ArcscriptParserBase.cpp
create mode 100755 Cpp/src/ArcscriptParserBase.h
create mode 100755 Cpp/src/ArcscriptTranspiler.cpp
create mode 100755 Cpp/src/ArcscriptTranspiler.h
create mode 100755 Cpp/src/ArcscriptVisitor.cpp
create mode 100755 Cpp/src/ArcscriptVisitor.h
diff --git a/Cpp/.gitignore b/Cpp/.gitignore
index 21bc544..817844d 100644
--- a/Cpp/.gitignore
+++ b/Cpp/.gitignore
@@ -1 +1,2 @@
-src/Generated
\ No newline at end of file
+src/Generated
+build
\ No newline at end of file
diff --git a/Cpp/CMakeLists.txt b/Cpp/CMakeLists.txt
new file mode 100755
index 0000000..25096c9
--- /dev/null
+++ b/Cpp/CMakeLists.txt
@@ -0,0 +1,70 @@
+# minimum required CMAKE version
+CMAKE_MINIMUM_REQUIRED(VERSION 3.10 FATAL_ERROR)
+
+set(PROJECT_VERSION "0.1.0")
+project(ArcscriptTranspiler VERSION ${PROJECT_VERSION})
+
+list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake)
+message(CMAKE_CXX_COMPILER_ID=${CMAKE_CXX_COMPILER_ID})
+# compiler must be 17
+set(CMAKE_CXX_STANDARD 17)
+set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON)
+# required if linking to static library
+#add_definitions(-DANTLR4CPP_STATIC)
+
+# using /MD flag for antlr4_runtime (for Visual C++ compilers only)
+set(ANTLR4_WITH_STATIC_CRT OFF)
+
+# Specify the version of the antlr4 library needed for this project.
+# By default the latest version of antlr4 will be used. You can specify a
+# specific, stable version by setting a repository tag value or a link
+# to a zip file containing the libary source.
+ set(ANTLR4_TAG 4.13.1)
+# set(ANTLR4_ZIP_REPOSITORY https://github.com/antlr/antlr4/archive/refs/tags/4.13.2.zip)
+
+# add external build for antlrcpp
+include(ExternalAntlr4Cpp)
+# add antlr4cpp artifacts to project environment
+include_directories(${ANTLR4_INCLUDE_DIRS})
+
+## set variable pointing to the antlr tool that supports C++
+## this is not required if the jar file can be found under PATH environment
+#set(ANTLR_EXECUTABLE /home/user/antlr-4.13.2-complete.jar)
+## add macros to generate ANTLR Cpp code from grammar
+#find_package(ANTLR REQUIRED)
+#
+## Call macro to add lexer and grammar to your build dependencies.
+#antlr_target(SampleGrammarLexer TLexer.g4 LEXER
+# PACKAGE antlrcpptest)
+#antlr_target(SampleGrammarParser TParser.g4 PARSER
+# PACKAGE antlrcpptest
+# DEPENDS_ANTLR SampleGrammarLexer
+# COMPILE_FLAGS -lib ${ANTLR_SampleGrammarLexer_OUTPUT_DIR})
+
+# include generated files in project environment
+#include_directories(${ANTLR_SampleGrammarLexer_OUTPUT_DIR})
+#include_directories(${ANTLR_SampleGrammarParser_OUTPUT_DIR})
+
+include_directories(src/Generated/ArcscriptLexer)
+include_directories(src/Generated/ArcscriptParser)
+include_directories(src)
+# add generated grammar to demo binary target
+#add_executable(demo main.cpp
+# src/Generated/ArcscriptLexer
+# src/Generated/ArcscriptParser)
+
+add_library(ArcscriptTranspiler SHARED)
+
+target_sources(ArcscriptTranspiler PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/src/ArcscriptTranspiler.cpp)
+
+set_target_properties(ArcscriptTranspiler PROPERTIES VERSION ${PROJECT_VERSION} SOVERSION ${PROJECT_VERSION})
+
+if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
+ # For MSVC, we need to link against the shared library
+ target_compile_options(ArcscriptTranspiler PRIVATE -Wall -Wextra)
+elseif(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
+ # For other compilers, we can link against the static library
+ target_compile_definitions(ArcscriptTranspiler PRIVATE WIN_EXPORT)
+endif()
+
+target_link_libraries(ArcscriptTranspiler antlr4_shared)
\ No newline at end of file
diff --git a/Cpp/cmake/ExternalAntlr4Cpp.cmake b/Cpp/cmake/ExternalAntlr4Cpp.cmake
new file mode 100755
index 0000000..678bf8b
--- /dev/null
+++ b/Cpp/cmake/ExternalAntlr4Cpp.cmake
@@ -0,0 +1,177 @@
+cmake_minimum_required(VERSION 3.10)
+
+if(POLICY CMP0114)
+ cmake_policy(SET CMP0114 NEW)
+endif()
+
+include(ExternalProject)
+
+set(ANTLR4_ROOT ${CMAKE_CURRENT_BINARY_DIR}/antlr4_runtime/src/antlr4_runtime)
+set(ANTLR4_INCLUDE_DIRS ${ANTLR4_ROOT}/runtime/Cpp/runtime/src)
+set(ANTLR4_GIT_REPOSITORY https://github.com/antlr/antlr4.git)
+if(NOT DEFINED ANTLR4_TAG)
+ # Set to branch name to keep library updated at the cost of needing to rebuild after 'clean'
+ # Set to commit hash to keep the build stable and does not need to rebuild after 'clean'
+ set(ANTLR4_TAG master)
+endif()
+
+# Ensure that the include dir already exists at configure time (to avoid cmake erroring
+# on non-existent include dirs)
+file(MAKE_DIRECTORY "${ANTLR4_INCLUDE_DIRS}")
+
+if(${CMAKE_GENERATOR} MATCHES "Visual Studio.*")
+ set(ANTLR4_OUTPUT_DIR ${ANTLR4_ROOT}/runtime/Cpp/runtime/$(Configuration))
+elseif(${CMAKE_GENERATOR} MATCHES "Xcode.*")
+ set(ANTLR4_OUTPUT_DIR ${ANTLR4_ROOT}/runtime/Cpp/runtime/$(CONFIGURATION))
+else()
+ set(ANTLR4_OUTPUT_DIR ${ANTLR4_ROOT}/runtime/Cpp/runtime)
+endif()
+
+if(MSVC)
+ set(ANTLR4_STATIC_LIBRARIES
+ ${ANTLR4_OUTPUT_DIR}/antlr4-runtime-static.lib)
+ set(ANTLR4_SHARED_LIBRARIES
+ ${ANTLR4_OUTPUT_DIR}/antlr4-runtime.lib)
+ set(ANTLR4_RUNTIME_LIBRARIES
+ ${ANTLR4_OUTPUT_DIR}/antlr4-runtime.dll)
+else()
+ set(ANTLR4_STATIC_LIBRARIES
+ ${ANTLR4_OUTPUT_DIR}/libantlr4-runtime.a)
+ if(MINGW)
+ set(ANTLR4_SHARED_LIBRARIES
+ ${ANTLR4_OUTPUT_DIR}/libantlr4-runtime.dll.a)
+ set(ANTLR4_RUNTIME_LIBRARIES
+ ${ANTLR4_OUTPUT_DIR}/libantlr4-runtime.dll)
+ elseif(CYGWIN)
+ set(ANTLR4_SHARED_LIBRARIES
+ ${ANTLR4_OUTPUT_DIR}/libantlr4-runtime.dll.a)
+ set(ANTLR4_RUNTIME_LIBRARIES
+ ${ANTLR4_OUTPUT_DIR}/cygantlr4-runtime-4.13.2.dll)
+ elseif(APPLE)
+ set(ANTLR4_RUNTIME_LIBRARIES
+ ${ANTLR4_OUTPUT_DIR}/libantlr4-runtime.dylib)
+ else()
+ set(ANTLR4_RUNTIME_LIBRARIES
+ ${ANTLR4_OUTPUT_DIR}/libantlr4-runtime.so)
+ endif()
+endif()
+
+if(${CMAKE_GENERATOR} MATCHES ".* Makefiles")
+ # This avoids
+ # 'warning: jobserver unavailable: using -j1. Add '+' to parent make rule.'
+ set(ANTLR4_BUILD_COMMAND $(MAKE))
+elseif(${CMAKE_GENERATOR} MATCHES "Visual Studio.*")
+ set(ANTLR4_BUILD_COMMAND
+ ${CMAKE_COMMAND}
+ --build .
+ --config $(Configuration)
+ --target)
+elseif(${CMAKE_GENERATOR} MATCHES "Xcode.*")
+ set(ANTLR4_BUILD_COMMAND
+ ${CMAKE_COMMAND}
+ --build .
+ --config $(CONFIGURATION)
+ --target)
+else()
+ set(ANTLR4_BUILD_COMMAND
+ ${CMAKE_COMMAND}
+ --build .
+ --target)
+endif()
+
+if(NOT DEFINED ANTLR4_WITH_STATIC_CRT)
+ set(ANTLR4_WITH_STATIC_CRT ON)
+endif()
+
+if(ANTLR4_ZIP_REPOSITORY)
+ ExternalProject_Add(
+ antlr4_runtime
+ PREFIX antlr4_runtime
+ URL ${ANTLR4_ZIP_REPOSITORY}
+ DOWNLOAD_DIR ${CMAKE_CURRENT_BINARY_DIR}
+ BUILD_COMMAND ""
+ BUILD_IN_SOURCE 1
+ SOURCE_DIR ${ANTLR4_ROOT}
+ SOURCE_SUBDIR runtime/Cpp
+ CMAKE_CACHE_ARGS
+ -DCMAKE_BUILD_TYPE:STRING=${CMAKE_BUILD_TYPE}
+ -DWITH_STATIC_CRT:BOOL=${ANTLR4_WITH_STATIC_CRT}
+ -DDISABLE_WARNINGS:BOOL=ON
+ # -DCMAKE_CXX_STANDARD:STRING=17 # if desired, compile the runtime with a different C++ standard
+ # -DCMAKE_CXX_STANDARD:STRING=${CMAKE_CXX_STANDARD} # alternatively, compile the runtime with the same C++ standard as the outer project
+ INSTALL_COMMAND ""
+ EXCLUDE_FROM_ALL 1)
+else()
+ ExternalProject_Add(
+ antlr4_runtime
+ PREFIX antlr4_runtime
+ GIT_REPOSITORY ${ANTLR4_GIT_REPOSITORY}
+ GIT_TAG ${ANTLR4_TAG}
+ DOWNLOAD_DIR ${CMAKE_CURRENT_BINARY_DIR}
+ BUILD_COMMAND ""
+ BUILD_IN_SOURCE 1
+ SOURCE_DIR ${ANTLR4_ROOT}
+ SOURCE_SUBDIR runtime/Cpp
+ CMAKE_CACHE_ARGS
+ -DCMAKE_BUILD_TYPE:STRING=${CMAKE_BUILD_TYPE}
+ -DWITH_STATIC_CRT:BOOL=${ANTLR4_WITH_STATIC_CRT}
+ -DDISABLE_WARNINGS:BOOL=ON
+ # -DCMAKE_CXX_STANDARD:STRING=17 # if desired, compile the runtime with a different C++ standard
+ # -DCMAKE_CXX_STANDARD:STRING=${CMAKE_CXX_STANDARD} # alternatively, compile the runtime with the same C++ standard as the outer project
+ INSTALL_COMMAND ""
+ EXCLUDE_FROM_ALL 1)
+endif()
+
+# Separate build step as rarely people want both
+set(ANTLR4_BUILD_DIR ${ANTLR4_ROOT})
+if(${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.14.0")
+ # CMake 3.14 builds in above's SOURCE_SUBDIR when BUILD_IN_SOURCE is true
+ set(ANTLR4_BUILD_DIR ${ANTLR4_ROOT}/runtime/Cpp)
+endif()
+
+ExternalProject_Add_Step(
+ antlr4_runtime
+ build_static
+ COMMAND ${ANTLR4_BUILD_COMMAND} antlr4_static
+ # Depend on target instead of step (a custom command)
+ # to avoid running dependent steps concurrently
+ DEPENDS antlr4_runtime
+ BYPRODUCTS ${ANTLR4_STATIC_LIBRARIES}
+ EXCLUDE_FROM_MAIN 1
+ WORKING_DIRECTORY ${ANTLR4_BUILD_DIR})
+ExternalProject_Add_StepTargets(antlr4_runtime build_static)
+
+add_library(antlr4_static STATIC IMPORTED)
+add_dependencies(antlr4_static antlr4_runtime-build_static)
+set_target_properties(antlr4_static PROPERTIES
+ IMPORTED_LOCATION ${ANTLR4_STATIC_LIBRARIES})
+target_include_directories(antlr4_static
+ INTERFACE
+ ${ANTLR4_INCLUDE_DIRS}
+)
+
+ExternalProject_Add_Step(
+ antlr4_runtime
+ build_shared
+ COMMAND ${ANTLR4_BUILD_COMMAND} antlr4_shared
+ # Depend on target instead of step (a custom command)
+ # to avoid running dependent steps concurrently
+ DEPENDS antlr4_runtime
+ BYPRODUCTS ${ANTLR4_SHARED_LIBRARIES} ${ANTLR4_RUNTIME_LIBRARIES}
+ EXCLUDE_FROM_MAIN 1
+ WORKING_DIRECTORY ${ANTLR4_BUILD_DIR})
+ExternalProject_Add_StepTargets(antlr4_runtime build_shared)
+
+add_library(antlr4_shared SHARED IMPORTED)
+add_dependencies(antlr4_shared antlr4_runtime-build_shared)
+set_target_properties(antlr4_shared PROPERTIES
+ IMPORTED_LOCATION ${ANTLR4_RUNTIME_LIBRARIES})
+target_include_directories(antlr4_shared
+ INTERFACE
+ ${ANTLR4_INCLUDE_DIRS}
+)
+
+if(ANTLR4_SHARED_LIBRARIES)
+ set_target_properties(antlr4_shared PROPERTIES
+ IMPORTED_IMPLIB ${ANTLR4_SHARED_LIBRARIES})
+endif()
\ No newline at end of file
diff --git a/Cpp/cmake/FindANTLR.cmake b/Cpp/cmake/FindANTLR.cmake
new file mode 100755
index 0000000..0c10d9d
--- /dev/null
+++ b/Cpp/cmake/FindANTLR.cmake
@@ -0,0 +1,124 @@
+find_package(Java QUIET COMPONENTS Runtime)
+
+if(NOT ANTLR_EXECUTABLE)
+ find_program(ANTLR_EXECUTABLE
+ NAMES antlr.jar antlr4.jar antlr-4.jar antlr-4.13.2-complete.jar)
+endif()
+
+if(ANTLR_EXECUTABLE AND Java_JAVA_EXECUTABLE)
+ execute_process(
+ COMMAND ${Java_JAVA_EXECUTABLE} -jar ${ANTLR_EXECUTABLE}
+ OUTPUT_VARIABLE ANTLR_COMMAND_OUTPUT
+ ERROR_VARIABLE ANTLR_COMMAND_ERROR
+ RESULT_VARIABLE ANTLR_COMMAND_RESULT
+ OUTPUT_STRIP_TRAILING_WHITESPACE)
+
+ if(ANTLR_COMMAND_RESULT EQUAL 0)
+ string(REGEX MATCH "Version [0-9]+(\\.[0-9]+)*" ANTLR_VERSION ${ANTLR_COMMAND_OUTPUT})
+ string(REPLACE "Version " "" ANTLR_VERSION ${ANTLR_VERSION})
+ else()
+ message(
+ SEND_ERROR
+ "Command '${Java_JAVA_EXECUTABLE} -jar ${ANTLR_EXECUTABLE}' "
+ "failed with the output '${ANTLR_COMMAND_ERROR}'")
+ endif()
+
+ macro(ANTLR_TARGET Name InputFile)
+ set(ANTLR_OPTIONS LEXER PARSER LISTENER VISITOR)
+ set(ANTLR_ONE_VALUE_ARGS PACKAGE OUTPUT_DIRECTORY DEPENDS_ANTLR)
+ set(ANTLR_MULTI_VALUE_ARGS COMPILE_FLAGS DEPENDS)
+ cmake_parse_arguments(ANTLR_TARGET
+ "${ANTLR_OPTIONS}"
+ "${ANTLR_ONE_VALUE_ARGS}"
+ "${ANTLR_MULTI_VALUE_ARGS}"
+ ${ARGN})
+
+ set(ANTLR_${Name}_INPUT ${InputFile})
+
+ get_filename_component(ANTLR_INPUT ${InputFile} NAME_WE)
+
+ if(ANTLR_TARGET_OUTPUT_DIRECTORY)
+ set(ANTLR_${Name}_OUTPUT_DIR ${ANTLR_TARGET_OUTPUT_DIRECTORY})
+ else()
+ set(ANTLR_${Name}_OUTPUT_DIR
+ ${CMAKE_CURRENT_BINARY_DIR}/antlr4cpp_generated_src/${ANTLR_INPUT})
+ endif()
+
+ unset(ANTLR_${Name}_CXX_OUTPUTS)
+
+ if((ANTLR_TARGET_LEXER AND NOT ANTLR_TARGET_PARSER) OR
+ (ANTLR_TARGET_PARSER AND NOT ANTLR_TARGET_LEXER))
+ list(APPEND ANTLR_${Name}_CXX_OUTPUTS
+ ${ANTLR_${Name}_OUTPUT_DIR}/${ANTLR_INPUT}.h
+ ${ANTLR_${Name}_OUTPUT_DIR}/${ANTLR_INPUT}.cpp)
+ set(ANTLR_${Name}_OUTPUTS
+ ${ANTLR_${Name}_OUTPUT_DIR}/${ANTLR_INPUT}.interp
+ ${ANTLR_${Name}_OUTPUT_DIR}/${ANTLR_INPUT}.tokens)
+ else()
+ list(APPEND ANTLR_${Name}_CXX_OUTPUTS
+ ${ANTLR_${Name}_OUTPUT_DIR}/${ANTLR_INPUT}Lexer.h
+ ${ANTLR_${Name}_OUTPUT_DIR}/${ANTLR_INPUT}Lexer.cpp
+ ${ANTLR_${Name}_OUTPUT_DIR}/${ANTLR_INPUT}Parser.h
+ ${ANTLR_${Name}_OUTPUT_DIR}/${ANTLR_INPUT}Parser.cpp)
+ list(APPEND ANTLR_${Name}_OUTPUTS
+ ${ANTLR_${Name}_OUTPUT_DIR}/${ANTLR_INPUT}Lexer.interp
+ ${ANTLR_${Name}_OUTPUT_DIR}/${ANTLR_INPUT}Lexer.tokens)
+ endif()
+
+ if(ANTLR_TARGET_LISTENER)
+ list(APPEND ANTLR_${Name}_CXX_OUTPUTS
+ ${ANTLR_${Name}_OUTPUT_DIR}/${ANTLR_INPUT}BaseListener.h
+ ${ANTLR_${Name}_OUTPUT_DIR}/${ANTLR_INPUT}BaseListener.cpp
+ ${ANTLR_${Name}_OUTPUT_DIR}/${ANTLR_INPUT}Listener.h
+ ${ANTLR_${Name}_OUTPUT_DIR}/${ANTLR_INPUT}Listener.cpp)
+ list(APPEND ANTLR_TARGET_COMPILE_FLAGS -listener)
+ endif()
+
+ if(ANTLR_TARGET_VISITOR)
+ list(APPEND ANTLR_${Name}_CXX_OUTPUTS
+ ${ANTLR_${Name}_OUTPUT_DIR}/${ANTLR_INPUT}BaseVisitor.h
+ ${ANTLR_${Name}_OUTPUT_DIR}/${ANTLR_INPUT}BaseVisitor.cpp
+ ${ANTLR_${Name}_OUTPUT_DIR}/${ANTLR_INPUT}Visitor.h
+ ${ANTLR_${Name}_OUTPUT_DIR}/${ANTLR_INPUT}Visitor.cpp)
+ list(APPEND ANTLR_TARGET_COMPILE_FLAGS -visitor)
+ endif()
+
+ if(ANTLR_TARGET_PACKAGE)
+ list(APPEND ANTLR_TARGET_COMPILE_FLAGS -package ${ANTLR_TARGET_PACKAGE})
+ endif()
+
+ list(APPEND ANTLR_${Name}_OUTPUTS ${ANTLR_${Name}_CXX_OUTPUTS})
+
+ if(ANTLR_TARGET_DEPENDS_ANTLR)
+ if(ANTLR_${ANTLR_TARGET_DEPENDS_ANTLR}_INPUT)
+ list(APPEND ANTLR_TARGET_DEPENDS
+ ${ANTLR_${ANTLR_TARGET_DEPENDS_ANTLR}_INPUT})
+ list(APPEND ANTLR_TARGET_DEPENDS
+ ${ANTLR_${ANTLR_TARGET_DEPENDS_ANTLR}_OUTPUTS})
+ else()
+ message(SEND_ERROR
+ "ANTLR target '${ANTLR_TARGET_DEPENDS_ANTLR}' not found")
+ endif()
+ endif()
+
+ add_custom_command(
+ OUTPUT ${ANTLR_${Name}_OUTPUTS}
+ COMMAND ${Java_JAVA_EXECUTABLE} -jar ${ANTLR_EXECUTABLE}
+ ${InputFile}
+ -o ${ANTLR_${Name}_OUTPUT_DIR}
+ -no-listener
+ -Dlanguage=Cpp
+ ${ANTLR_TARGET_COMPILE_FLAGS}
+ DEPENDS ${InputFile}
+ ${ANTLR_TARGET_DEPENDS}
+ WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
+ COMMENT "Building ${Name} with ANTLR ${ANTLR_VERSION}")
+ endmacro(ANTLR_TARGET)
+
+endif(ANTLR_EXECUTABLE AND Java_JAVA_EXECUTABLE)
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(
+ ANTLR
+ REQUIRED_VARS ANTLR_EXECUTABLE Java_JAVA_EXECUTABLE
+ VERSION_VAR ANTLR_VERSION)
\ No newline at end of file
diff --git a/Cpp/cmake/antlr4-generator.cmake.in b/Cpp/cmake/antlr4-generator.cmake.in
new file mode 100755
index 0000000..4cfd908
--- /dev/null
+++ b/Cpp/cmake/antlr4-generator.cmake.in
@@ -0,0 +1,181 @@
+set(ANTLR_VERSION @ANTLR_VERSION@)
+
+@PACKAGE_INIT@
+
+if (NOT ANTLR4_CPP_GENERATED_SRC_DIR)
+ set(ANTLR4_GENERATED_SRC_DIR ${CMAKE_BINARY_DIR}/antlr4_generated_src)
+endif()
+
+FIND_PACKAGE(Java COMPONENTS Runtime REQUIRED)
+
+#
+# The ANTLR generator will output the following files given the input file f.g4
+#
+# Input -> f.g4
+# Output -> f.h
+# -> f.cpp
+#
+# the following files will only be produced if there is a parser contained
+# Flag -visitor active
+# Output -> BaseVisitor.h
+# -> BaseVisitor.cpp
+# -> Visitor.h
+# -> Visitor.cpp
+#
+# Flag -listener active
+# Output -> BaseListener.h
+# -> BaseListener.cpp
+# -> Listener.h
+# -> Listener.cpp
+#
+# See documentation in markup
+#
+function(antlr4_generate
+ Antlr4_ProjectTarget
+ Antlr4_InputFile
+ Antlr4_GeneratorType
+ )
+
+ set( Antlr4_GeneratedSrcDir ${ANTLR4_GENERATED_SRC_DIR}/${Antlr4_ProjectTarget} )
+
+ get_filename_component(Antlr4_InputFileBaseName ${Antlr4_InputFile} NAME_WE )
+
+ list( APPEND Antlr4_GeneratorStatusMessage "Common Include-, Source- and Tokenfiles" )
+
+ if ( ${Antlr4_GeneratorType} STREQUAL "LEXER")
+ set(Antlr4_LexerBaseName "${Antlr4_InputFileBaseName}")
+ set(Antlr4_ParserBaseName "")
+ else()
+ if ( ${Antlr4_GeneratorType} STREQUAL "PARSER")
+ set(Antlr4_LexerBaseName "")
+ set(Antlr4_ParserBaseName "${Antlr4_InputFileBaseName}")
+ else()
+ if ( ${Antlr4_GeneratorType} STREQUAL "BOTH")
+ set(Antlr4_LexerBaseName "${Antlr4_InputFileBaseName}Lexer")
+ set(Antlr4_ParserBaseName "${Antlr4_InputFileBaseName}Parser")
+ else()
+ message(FATAL_ERROR "The third parameter must be LEXER, PARSER or BOTH")
+ endif ()
+ endif ()
+ endif ()
+
+ # Prepare list of generated targets
+ list( APPEND Antlr4_GeneratedTargets "${Antlr4_GeneratedSrcDir}/${Antlr4_InputFileBaseName}.tokens" )
+ list( APPEND Antlr4_GeneratedTargets "${Antlr4_GeneratedSrcDir}/${Antlr4_InputFileBaseName}.interp" )
+ list( APPEND DependentTargets "${Antlr4_GeneratedSrcDir}/${Antlr4_InputFileBaseName}.tokens" )
+
+ if ( NOT ${Antlr4_LexerBaseName} STREQUAL "" )
+ list( APPEND Antlr4_GeneratedTargets "${Antlr4_GeneratedSrcDir}/${Antlr4_LexerBaseName}.h" )
+ list( APPEND Antlr4_GeneratedTargets "${Antlr4_GeneratedSrcDir}/${Antlr4_LexerBaseName}.cpp" )
+ endif ()
+
+ if ( NOT ${Antlr4_ParserBaseName} STREQUAL "" )
+ list( APPEND Antlr4_GeneratedTargets "${Antlr4_GeneratedSrcDir}/${Antlr4_ParserBaseName}.h" )
+ list( APPEND Antlr4_GeneratedTargets "${Antlr4_GeneratedSrcDir}/${Antlr4_ParserBaseName}.cpp" )
+ endif ()
+
+ # process optional arguments ...
+
+ if ( ( ARGC GREATER_EQUAL 4 ) AND ARGV3 )
+ set(Antlr4_BuildListenerOption "-listener")
+
+ list( APPEND Antlr4_GeneratedTargets "${Antlr4_GeneratedSrcDir}/${Antlr4_InputFileBaseName}BaseListener.h" )
+ list( APPEND Antlr4_GeneratedTargets "${Antlr4_GeneratedSrcDir}/${Antlr4_InputFileBaseName}BaseListener.cpp" )
+ list( APPEND Antlr4_GeneratedTargets "${Antlr4_GeneratedSrcDir}/${Antlr4_InputFileBaseName}Listener.h" )
+ list( APPEND Antlr4_GeneratedTargets "${Antlr4_GeneratedSrcDir}/${Antlr4_InputFileBaseName}Listener.cpp" )
+
+ list( APPEND Antlr4_GeneratorStatusMessage ", Listener Include- and Sourcefiles" )
+ else()
+ set(Antlr4_BuildListenerOption "-no-listener")
+ endif ()
+
+ if ( ( ARGC GREATER_EQUAL 5 ) AND ARGV4 )
+ set(Antlr4_BuildVisitorOption "-visitor")
+
+ list( APPEND Antlr4_GeneratedTargets "${Antlr4_GeneratedSrcDir}/${Antlr4_InputFileBaseName}BaseVisitor.h" )
+ list( APPEND Antlr4_GeneratedTargets "${Antlr4_GeneratedSrcDir}/${Antlr4_InputFileBaseName}BaseVisitor.cpp" )
+ list( APPEND Antlr4_GeneratedTargets "${Antlr4_GeneratedSrcDir}/${Antlr4_InputFileBaseName}Visitor.h" )
+ list( APPEND Antlr4_GeneratedTargets "${Antlr4_GeneratedSrcDir}/${Antlr4_InputFileBaseName}Visitor.cpp" )
+
+ list( APPEND Antlr4_GeneratorStatusMessage ", Visitor Include- and Sourcefiles" )
+ else()
+ set(Antlr4_BuildVisitorOption "-no-visitor")
+ endif ()
+
+ if ( (ARGC GREATER_EQUAL 6 ) AND (NOT ${ARGV5} STREQUAL "") )
+ set(Antlr4_NamespaceOption "-package;${ARGV5}")
+
+ list( APPEND Antlr4_GeneratorStatusMessage " in Namespace ${ARGV5}" )
+ else()
+ set(Antlr4_NamespaceOption "")
+ endif ()
+
+ if ( (ARGC GREATER_EQUAL 7 ) AND (NOT ${ARGV6} STREQUAL "") )
+ set(Antlr4_AdditionalDependencies ${ARGV6})
+ else()
+ set(Antlr4_AdditionalDependencies "")
+ endif ()
+
+ if ( (ARGC GREATER_EQUAL 8 ) AND (NOT ${ARGV7} STREQUAL "") )
+ set(Antlr4_LibOption "-lib;${ARGV7}")
+
+ list( APPEND Antlr4_GeneratorStatusMessage " using Library ${ARGV7}" )
+ else()
+ set(Antlr4_LibOption "")
+ endif ()
+
+ if(NOT Java_FOUND)
+ message(FATAL_ERROR "Java is required to process grammar or lexer files! - Use 'FIND_PACKAGE(Java COMPONENTS Runtime REQUIRED)'")
+ endif()
+
+ if(NOT EXISTS "${ANTLR4_JAR_LOCATION}")
+ message(FATAL_ERROR "Unable to find antlr tool. ANTLR4_JAR_LOCATION:${ANTLR4_JAR_LOCATION}")
+ endif()
+
+ # The call to generate the files
+ add_custom_command(
+ OUTPUT ${Antlr4_GeneratedTargets}
+ # Remove target directory
+ COMMAND
+ ${CMAKE_COMMAND} -E remove_directory ${Antlr4_GeneratedSrcDir}
+ # Create target directory
+ COMMAND
+ ${CMAKE_COMMAND} -E make_directory ${Antlr4_GeneratedSrcDir}
+ COMMAND
+ # Generate files
+ "${Java_JAVA_EXECUTABLE}" -jar "${ANTLR4_JAR_LOCATION}" -Werror -Dlanguage=Cpp ${Antlr4_BuildListenerOption} ${Antlr4_BuildVisitorOption} ${Antlr4_LibOption} ${ANTLR4_GENERATED_OPTIONS} -o "${Antlr4_GeneratedSrcDir}" ${Antlr4_NamespaceOption} "${Antlr4_InputFile}"
+ WORKING_DIRECTORY "${CMAKE_BINARY_DIR}"
+ MAIN_DEPENDENCY "${Antlr4_InputFile}"
+ DEPENDS ${Antlr4_AdditionalDependencies}
+ )
+
+ # set output variables in parent scope
+ set( ANTLR4_INCLUDE_DIR_${Antlr4_ProjectTarget} ${Antlr4_GeneratedSrcDir} PARENT_SCOPE)
+ set( ANTLR4_SRC_FILES_${Antlr4_ProjectTarget} ${Antlr4_GeneratedTargets} PARENT_SCOPE)
+ set( ANTLR4_TOKEN_FILES_${Antlr4_ProjectTarget} ${DependentTargets} PARENT_SCOPE)
+ set( ANTLR4_TOKEN_DIRECTORY_${Antlr4_ProjectTarget} ${Antlr4_GeneratedSrcDir} PARENT_SCOPE)
+
+ # export generated cpp files into list
+ foreach(generated_file ${Antlr4_GeneratedTargets})
+
+ if (NOT CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
+ set_source_files_properties(
+ ${generated_file}
+ PROPERTIES
+ COMPILE_FLAGS -Wno-overloaded-virtual
+ )
+ endif ()
+
+ if (CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
+ set_source_files_properties(
+ ${generated_file}
+ PROPERTIES
+ COMPILE_FLAGS -wd4251
+ )
+ endif ()
+
+ endforeach(generated_file)
+
+message(STATUS "Antlr4 ${Antlr4_ProjectTarget} - Building " ${Antlr4_GeneratorStatusMessage} )
+
+endfunction()
\ No newline at end of file
diff --git a/Cpp/cmake/antlr4-runtime.cmake.in b/Cpp/cmake/antlr4-runtime.cmake.in
new file mode 100755
index 0000000..04f5252
--- /dev/null
+++ b/Cpp/cmake/antlr4-runtime.cmake.in
@@ -0,0 +1,13 @@
+set(ANTLR_VERSION @ANTLR_VERSION@)
+
+@PACKAGE_INIT@
+
+set_and_check(ANTLR4_INCLUDE_DIR "@PACKAGE_ANTLR4_INCLUDE_DIR@")
+set_and_check(ANTLR4_LIB_DIR "@PACKAGE_ANTLR4_LIB_DIR@")
+
+include(CMakeFindDependencyMacro)
+find_dependency(Threads)
+
+include(${CMAKE_CURRENT_LIST_DIR}/@targets_export_name@.cmake)
+
+check_required_components(antlr)
\ No newline at end of file
diff --git a/Cpp/src/ArcscriptErrorExceptions.h b/Cpp/src/ArcscriptErrorExceptions.h
new file mode 100755
index 0000000..95e634d
--- /dev/null
+++ b/Cpp/src/ArcscriptErrorExceptions.h
@@ -0,0 +1,54 @@
+#pragma once
+
+#include
+#include
+#include
+#include
+
+namespace Arcweave {
+ class RuntimeErrorException : public std::exception {
+ public:
+ std::string message;
+ int line = -1;
+ int charPositionInLine = -1;
+ RuntimeErrorException(std::string msg) {
+ message = msg;
+ };
+ RuntimeErrorException(std::string msg, size_t _line, size_t _charPositionInLine) {
+ message = msg;
+ line = _line;
+ charPositionInLine = _charPositionInLine;
+ };
+ char const* what() const noexcept override {
+ if (line > -1) {
+ std::ostringstream oss;
+ oss << "line " << line << ":" << charPositionInLine << " " << message << std::endl;
+ return oss.str().c_str();
+ }
+ return message.c_str();
+ }
+ };
+
+ class ParseErrorException : public std::exception {
+ public:
+ std::string message;
+ int line = -1;
+ int charPositionInLine = -1;
+ ParseErrorException(std::string msg) {
+ message = msg;
+ };
+ ParseErrorException(std::string msg, size_t _line, size_t _charPositionInLine) {
+ message = msg;
+ line = _line;
+ charPositionInLine = _charPositionInLine;
+ };
+ char const* what() const noexcept override {
+ if (line > -1) {
+ std::ostringstream oss;
+ oss << "line " << line << ":" << charPositionInLine << " " << message << std::endl;
+ return oss.str().c_str();
+ }
+ return message.c_str();
+ }
+ };
+}
\ No newline at end of file
diff --git a/Cpp/src/ArcscriptErrorListener.cpp b/Cpp/src/ArcscriptErrorListener.cpp
new file mode 100755
index 0000000..6cf0c84
--- /dev/null
+++ b/Cpp/src/ArcscriptErrorListener.cpp
@@ -0,0 +1,12 @@
+#include "ArcscriptErrorListener.h"
+#include "ArcscriptErrorExceptions.h"
+
+using namespace antlr4;
+using namespace Arcweave;
+
+ErrorListener ErrorListener::INSTANCE;
+
+void ErrorListener::syntaxError(Recognizer * /*recognizer*/, Token * /*offendingSymbol*/,
+ size_t line, size_t charPositionInLine, const std::string &msg, std::exception_ptr /*e*/) {
+ throw ParseErrorException(msg, line, charPositionInLine);
+}
\ No newline at end of file
diff --git a/Cpp/src/ArcscriptErrorListener.h b/Cpp/src/ArcscriptErrorListener.h
new file mode 100755
index 0000000..5bf81bb
--- /dev/null
+++ b/Cpp/src/ArcscriptErrorListener.h
@@ -0,0 +1,14 @@
+#pragma once
+
+#include "BaseErrorListener.h"
+
+using namespace antlr4;
+
+namespace Arcweave {
+ class ErrorListener : public BaseErrorListener {
+ public:
+ static ErrorListener INSTANCE;
+ void syntaxError(Recognizer *recognizer, Token *offendingSymbol, size_t line,
+ size_t charPositionInLine, const std::string &msg, std::exception_ptr e);
+ };
+}
\ No newline at end of file
diff --git a/Cpp/src/ArcscriptExpression.cpp b/Cpp/src/ArcscriptExpression.cpp
new file mode 100755
index 0000000..4064338
--- /dev/null
+++ b/Cpp/src/ArcscriptExpression.cpp
@@ -0,0 +1,312 @@
+#include "ArcscriptExpression.h"
+#include
+
+namespace Arcweave {
+
+std::string Expression::valueToString(std::any value)
+{
+ if (value.type() == typeid(std::string))
+ {
+ return std::any_cast(value);
+ }
+ if (value.type() == typeid(bool))
+ {
+ return std::any_cast(value) ? "true" : "false";
+ }
+ if (value.type() == typeid(int))
+ {
+ return std::to_string(std::any_cast(value));
+ }
+ if (value.type() == typeid(double))
+ {
+ std::stringstream ss;
+ ss << std::any_cast(value);
+ return ss.str();
+ }
+
+ return NULL;
+}
+
+
+Expression::NumberValues Expression::doubleValues(std::any value1, std::any value2) {
+ int intValue1, intValue2;
+ double dblValue1, dblValue2;
+ bool isDouble = false;
+ if (value1.type() == typeid(int)) {
+ intValue1 = std::any_cast(value1);
+ dblValue1 = intValue1;
+ } else if (value1.type() == typeid(double)){ // type double;
+ isDouble = true;
+ dblValue1 = std::any_cast(value1);
+ } else if (value1.type() == typeid(bool)) {
+ bool boolVal = std::any_cast(value1);
+ if (boolVal) {
+ dblValue1 = 1;
+ } else {
+ dblValue1 = 0;
+ }
+ }
+ if (value2.type() == typeid(int)) {
+ intValue2 = std::any_cast(value2);
+ dblValue2 = intValue2;
+ } else if (value2.type() == typeid(double)) {
+ isDouble = true;
+ dblValue2 = std::any_cast(value2);
+ } else if (value2.type() == typeid(bool)) {
+ bool boolVal = std::any_cast(value1);
+ if (boolVal) {
+ dblValue2 = 1;
+ } else {
+ dblValue2 = 0;
+ }
+ }
+ NumberValues returnVal;
+ returnVal.value1 = dblValue1;
+ returnVal.value2 = dblValue2;
+ returnVal.hasDoubles = isDouble;
+ return returnVal;
+}
+
+bool Expression::valueToBool(std::any value) {
+ if (value.type() == typeid(int)) {
+ return (std::any_cast(value) > 0);
+ }
+ if (value.type() == typeid(double)) {
+ return (std::any_cast(value) > 0);
+ }
+ if (value.type() == typeid(std::string)) {
+ return (std::any_cast(value) != "");
+ }
+ return (std::any_cast(value));
+}
+
+Expression Expression::operator+ (const Expression &other) {
+ if (value.type() == typeid(std::string) || other.value.type() == typeid(std::string))
+ {
+ return new Expression(valueToString(value) + valueToString(other.value));
+ }
+ NumberValues values = doubleValues(value, other.value);
+ Expression* result;
+ if (!values.hasDoubles) {
+ int intValue = values.value1 + values.value2;
+ result = new Expression(intValue);
+ } else {
+ result = new Expression(values.value1 + values.value2);
+ }
+ return *result;
+}
+
+Expression Expression::operator- (const Expression &other) {
+ NumberValues values = doubleValues(value, other.value);
+ Expression* result;
+ if (!values.hasDoubles) {
+ int intValue = values.value1 - values.value2;
+ result = new Expression(intValue);
+ } else {
+ result = new Expression(values.value1 - values.value2);
+ }
+ return *result;
+}
+
+Expression Expression::operator* (const Expression &other) {
+ NumberValues values = doubleValues(value, other.value);
+ Expression* result;
+ if (!values.hasDoubles) {
+ int intValue = values.value1 * values.value2;
+ result = new Expression(intValue);
+ } else {
+ result = new Expression(values.value1 * values.value2);
+ }
+ return *result;
+}
+
+Expression Expression::operator* (const int other) {
+ NumberValues values = doubleValues(value, other);
+ Expression* result;
+ if (!values.hasDoubles) {
+ int intValue = values.value1 * values.value2;
+ result = new Expression(intValue);
+ } else {
+ result = new Expression(values.value1 * values.value2);
+ }
+ return *result;
+}
+
+Expression Expression::operator/ (const Expression &other) {
+ NumberValues values = doubleValues(value, other.value);
+ Expression* result;
+ if (!values.hasDoubles) {
+ int intValue = values.value1 / values.value2;
+ result = new Expression(intValue);
+ } else {
+ result = new Expression(values.value1 / values.value2);
+ }
+ return *result;
+}
+
+Expression Expression::operator+= (const Expression &other) {
+ if (value.type() == typeid(int) || value.type() == typeid(double)) {
+ NumberValues values = doubleValues(value, other.value);
+ if (!values.hasDoubles) {
+ int intValue = values.value1 + values.value2;
+ value = intValue;
+ } else {
+ value = values.value1 + values.value2;
+ }
+ }
+ if (value.type() == typeid(std::string)) {
+ value = std::any_cast(value) + std::any_cast(other.value);
+ }
+ return *this;
+}
+
+Expression Expression::operator-= (const Expression &other) {
+ NumberValues values = doubleValues(value, other.value);
+ if (!values.hasDoubles) {
+ int intValue = values.value1 - values.value2;
+ value = intValue;
+ } else {
+ value = values.value1 - values.value2;
+ }
+ return *this;
+}
+
+Expression Expression::operator*= (const Expression &other) {
+ NumberValues values = doubleValues(value, other.value);
+ if (!values.hasDoubles) {
+ int intValue = values.value1 * values.value2;
+ value = intValue;
+ } else {
+ value = values.value1 * values.value2;
+ }
+ return *this;
+}
+
+Expression Expression::operator/= (const Expression &other) {
+ NumberValues values = doubleValues(value, other.value);
+ if (!values.hasDoubles) {
+ int intValue = values.value1 / values.value2;
+ value = intValue;
+ } else {
+ value = values.value1 / values.value2;
+ }
+ return *this;
+}
+
+bool Expression::operator== (const Expression &other) {
+ if (value.type() == typeid(int) || value.type() == typeid(double)) {
+ NumberValues values = doubleValues(value, other.value);
+ return values.value1 == values.value2;
+ }
+ if (value.type() == typeid(bool)) {
+ return std::any_cast(value) == std::any_cast(other.value);
+ }
+ return std::any_cast(value) == std::any_cast(other.value);
+}
+
+bool Expression::operator== (double other) {
+ NumberValues values = doubleValues(value, other);
+ return values.value1 == values.value2;
+}
+
+bool Expression::operator== (int other) {
+ NumberValues values = doubleValues(value, other);
+ return values.value1 == values.value2;
+}
+
+bool Expression::operator== (std::string other) {
+ return std::any_cast(value) == other;
+}
+
+bool Expression::operator== (bool other) {
+ return valueToBool(value) == other;
+}
+
+bool Expression::operator!= (const Expression &other) {
+ if (value.type() == typeid(int) || value.type() == typeid(double)) {
+ NumberValues values = doubleValues(value, other.value);
+ return values.value1 != values.value2;
+ }
+ if (value.type() == typeid(bool)) {
+ return std::any_cast(value) != std::any_cast(other.value);
+ }
+ return std::any_cast(value) != std::any_cast(other.value);
+}
+
+bool Expression::operator!= (double other) {
+ NumberValues values = doubleValues(value, other);
+ return values.value1 != values.value2;
+}
+
+bool Expression::operator!= (int other) {
+ NumberValues values = doubleValues(value, other);
+ return values.value1 != values.value2;
+}
+
+bool Expression::operator!= (std::string other) {
+ return std::any_cast(value) != other;
+}
+
+bool Expression::operator!= (const char other[]) {
+ return strcmp(std::any_cast(value).c_str(), other) == 0;
+}
+
+bool Expression::operator> (const Expression &other) {
+ NumberValues values = doubleValues(value, other.value);
+ return values.value1 > values.value2;
+}
+
+bool Expression::operator> (int other) {
+ NumberValues values = doubleValues(value, other);
+ return values.value1 > values.value2;
+}
+
+bool Expression::operator> (double other) {
+ NumberValues values = doubleValues(value, other);
+ return values.value1 > values.value2;
+}
+
+bool Expression::operator>= (const Expression &other) {
+ NumberValues values = doubleValues(value, other.value);
+ return values.value1 >= values.value2;
+}
+
+bool Expression::operator< (const Expression &other) {
+ NumberValues values = doubleValues(value, other.value);
+ return values.value1 < values.value2;
+}
+
+bool Expression::operator<= (const Expression &other) {
+ NumberValues values = doubleValues(value, other.value);
+ return values.value1 <= values.value2;
+}
+
+bool Expression::operator! () {
+ return !(valueToBool(value));
+}
+
+bool Expression::operator&& (const Expression &other) {
+ return valueToBool(value) && valueToBool(other.value);
+}
+
+bool Expression::operator|| (const Expression &other) {
+ return valueToBool(value) || valueToBool(other.value);
+}
+}
+
+std::ostream& operator<< (std::ostream& out, const Arcweave::Expression &e) {
+ std::any value = e.value;
+ if (value.type() == typeid(int)) {
+ return out << std::any_cast(value);
+ }
+ if (value.type() == typeid(double)) {
+ return out << std::any_cast(value);
+ }
+ if (value.type() == typeid(std::string)) {
+ return out << std::any_cast(value);
+ }
+ if (value.type() == typeid(bool)) {
+ return out << std::any_cast(value);
+ }
+ return out;
+}
\ No newline at end of file
diff --git a/Cpp/src/ArcscriptExpression.h b/Cpp/src/ArcscriptExpression.h
new file mode 100755
index 0000000..0a7c715
--- /dev/null
+++ b/Cpp/src/ArcscriptExpression.h
@@ -0,0 +1,81 @@
+#include
+#include
+#include
+#include
+
+namespace Arcweave {
+
+class Expression {
+private:
+ struct NumberValues {
+ double value1;
+ double value2;
+ bool hasDoubles = false;
+ };
+
+ static NumberValues doubleValues(std::any value1, std::any value2) ;
+
+ static std::string valueToString(std::any value);
+ static bool valueToBool(std::any value);
+public:
+ std::any value;
+ Expression() {
+ value = std::any();
+ }
+ Expression(std::string _value) {
+ value = _value;
+ }
+ Expression(bool _value) {
+ value = _value;
+ }
+ Expression(int _value) {
+ value = _value;
+ }
+ Expression(double _value) {
+ value = _value;
+ }
+ Expression(const Expression &e) {
+ value = e.value;
+ }
+
+ void setValue(std::any _value) {
+ value = _value;
+ }
+
+ const std::type_info& type() {
+ return value.type();
+ }
+
+ Expression operator+ (const Expression &other);
+ Expression operator- (const Expression &other);
+ Expression operator* (const Expression &other);
+ Expression operator* (const int other);
+ Expression operator/ (const Expression &other);
+ Expression operator+= (const Expression &other);
+ Expression operator-= (const Expression &other);
+ Expression operator*= (const Expression &other);
+ Expression operator/= (const Expression &other);
+
+ bool operator== (const Expression &other);
+ bool operator== (double other);
+ bool operator== (int other);
+ bool operator== (std::string other);
+ bool operator== (bool other);
+ bool operator!= (const Expression &other);
+ bool operator!= (double other);
+ bool operator!= (int other);
+ bool operator!= (std::string other);
+ bool operator!= (const char other[]);
+ bool operator> (const Expression &other);
+ bool operator> (int other);
+ bool operator> (double other);
+ bool operator>= (const Expression &other);
+ bool operator< (const Expression &other);
+ bool operator<= (const Expression &other);
+ bool operator! ();
+ bool operator&& (const Expression &other);
+ bool operator|| (const Expression &other);
+};
+
+}
+std::ostream& operator<< (std::ostream& out, const Arcweave::Expression &e);
\ No newline at end of file
diff --git a/Cpp/src/ArcscriptFunctions.cpp b/Cpp/src/ArcscriptFunctions.cpp
new file mode 100755
index 0000000..98cbea5
--- /dev/null
+++ b/Cpp/src/ArcscriptFunctions.cpp
@@ -0,0 +1,206 @@
+#include "ArcscriptFunctions.h"
+#include
+#include
+#include
+#include
+
+namespace Arcweave {
+ std::map ArcscriptFunctions::functions = {
+ { "abs", { 1, 1 } },
+ { "max", { 2, -1 }},
+ { "min", { 2, -1 }},
+ { "random", { 0, 0 }},
+ { "reset", { 1, -1 }},
+ { "resetAll", { 0, -1} },
+ { "roll", { 1, 2 } },
+ { "round", { 1, 1} },
+ { "show", { 1, -1 } },
+ { "sqr", { 1, 1 } },
+ { "sqrt", { 1, 1 } },
+ { "visits", { 0, 1 } },
+ };
+
+ std::any ArcscriptFunctions::Call(std::string functionName, std::vector _args) {
+ std::vector args;
+ for (std::any arg : _args) {
+ if (arg.type() == typeid(Expression)) {
+ args.push_back(std::any_cast(arg).value);
+ }
+ else {
+ args.push_back(arg);
+ }
+ }
+ std::any result;
+ if (functionName == "sqrt") {
+ result = this->Sqrt(args);
+ }
+ else if (functionName == "sqr") {
+ result = this->Sqr(args);
+ }
+ else if (functionName == "abs") {
+ result = this->Abs(args);
+ }
+ else if (functionName == "random") {
+ result = this->Random(args);
+ }
+ else if (functionName == "roll") {
+ result = this->Roll(args);
+ }
+ else if (functionName == "show") {
+ result = this->Show(args);
+ }
+ else if (functionName == "reset") {
+ result = this->Reset(args);
+ }
+ else if (functionName == "resetAll") {
+ result = this->ResetAll(args);
+ }
+ else if (functionName == "round") {
+ result = this->Round(args);
+ }
+ else if (functionName == "min") {
+ result = this->Min(args);
+ }
+ else if (functionName == "max") {
+ result = this->Max(args);
+ }
+ else if (functionName == "visits") {
+ result = this->Visits(args);
+ }
+ return result;
+ }
+
+ std::any ArcscriptFunctions::Sqrt(std::vector args) {
+
+ if (args[0].type() == typeid(int)) {
+ return sqrt(std::any_cast(args[0]));
+ }
+ return sqrt(std::any_cast(args[0]));
+ }
+
+ std::any ArcscriptFunctions::Sqr(std::vector args) {
+ if (args[0].type() == typeid(int)) {
+ int n = std::any_cast(args[0]);
+ return n * n;
+ }
+ double n = std::any_cast(args[0]);
+ return n * n;
+ }
+
+ std::any ArcscriptFunctions::Abs(std::vector args) {
+ if (args[0].type() == typeid(int)) {
+ return abs(std::any_cast(args[0]));
+ }
+ double n = std::any_cast(args[0]);
+ return abs(n);
+ }
+
+ std::any ArcscriptFunctions::Random(std::vector args) {
+ srand(time(NULL));
+ return ((double)rand() / (RAND_MAX));
+ }
+
+ std::any ArcscriptFunctions::Roll(std::vector args) {
+ int maxRoll = std::any_cast(args[0]);
+ int numRolls = 1;
+ if (args.size() == 2) {
+ numRolls = std::any_cast(args[1]);
+ }
+ int sum = 0;
+ for (int i = 0; i < numRolls; i++) {
+ int oneRoll = rand() % maxRoll + 1;
+ sum += oneRoll;
+ }
+ return sum;
+ }
+
+ std::any ArcscriptFunctions::Show(std::vector args) {
+ std::string result;
+ for (int i = 0; i < args.size(); i++) {
+ std::any arg = args[i];
+ if (arg.type() == typeid(int)) {
+ result += std::to_string(std::any_cast(arg));
+ }
+ else if (arg.type() == typeid(double)) {
+ result += std::to_string(std::any_cast(arg));
+ }
+ else if (arg.type() == typeid(bool)) {
+ result += std::to_string(std::any_cast(arg));
+ }
+ else if (arg.type() == typeid(std::string)) {
+ result += std::any_cast(arg);
+ }
+ }
+ _state->outputs.AddScriptOutput(result);
+ return std::any();
+ }
+
+ std::any ArcscriptFunctions::Round(std::vector args) {
+ if (args[0].type() == typeid(int)) {
+ return round(std::any_cast(args[0]));
+ }
+ double n = std::any_cast(args[0]);
+ return round(n);
+ }
+
+ std::any ArcscriptFunctions::Min(std::vector args) {
+ std::vector casted;
+ for (std::any arg : args) {
+ double val;
+ if (arg.type() == typeid(int)) {
+ val = std::any_cast(arg);
+ }
+ else {
+ val = std::any_cast(arg);
+ }
+ casted.push_back(val);
+ }
+ return *min_element(casted.begin(), casted.end());
+ }
+
+ std::any ArcscriptFunctions::Max(std::vector args) {
+ std::vector casted;
+ for (std::any arg : args) {
+ double val;
+ if (arg.type() == typeid(int)) {
+ val = std::any_cast(arg);
+ }
+ else {
+ val = std::any_cast(arg);
+ }
+ casted.push_back(val);
+ }
+ return *max_element(casted.begin(), casted.end());
+ }
+
+ std::any ArcscriptFunctions::Reset(std::vector args) {
+ std::vector variables;
+ for (std::any arg : args) {
+ variables.push_back(std::any_cast(arg));
+ }
+ _state->resetVars(variables);
+ return std::any();
+ }
+
+ std::any ArcscriptFunctions::ResetAll(std::vector args) {
+ std::vector except;
+ for (std::any arg : args) {
+ except.push_back(std::any_cast(arg));
+ }
+ _state->resetAllVars(except);
+ return std::any();
+ }
+
+ std::any ArcscriptFunctions::Visits(std::vector args) {
+ std::string nodeId = _state->currentElement;
+ if (args.size() > 0) {
+ Mention mention = std::any_cast(args[0]);
+
+ if (mention.attrs.count("data-id")) {
+ nodeId = mention.attrs["data-id"];
+ }
+ }
+
+ return _state->visits[nodeId];
+ }
+}
\ No newline at end of file
diff --git a/Cpp/src/ArcscriptFunctions.h b/Cpp/src/ArcscriptFunctions.h
new file mode 100755
index 0000000..1647409
--- /dev/null
+++ b/Cpp/src/ArcscriptFunctions.h
@@ -0,0 +1,40 @@
+#pragma once
+
+#include "ArcscriptHelpers.h"
+#include
+#include
+#include
+
+namespace Arcweave {
+class ArcscriptFunctions {
+private:
+ ArcscriptState *_state;
+
+public:
+ struct FunctionInfo {
+ int minArgs;
+ int maxArgs;
+ };
+
+ static std::map functions;
+
+ ArcscriptFunctions(ArcscriptState* state) : _state(state) {
+
+ }
+
+ std::any Call(std::string functionName, std::vector args);
+
+ std::any Abs(std::vector args);
+ std::any Max(std::vector args);
+ std::any Min(std::vector args);
+ std::any Random(std::vector args);
+ std::any Reset(std::vector args);
+ std::any ResetAll(std::vector args);
+ std::any Roll(std::vector args);
+ std::any Round(std::vector args);
+ std::any Show(std::vector args);
+ std::any Sqr(std::vector args);
+ std::any Sqrt(std::vector args);
+ std::any Visits(std::vector args);
+};
+}
\ No newline at end of file
diff --git a/Cpp/src/ArcscriptHelpers.h b/Cpp/src/ArcscriptHelpers.h
new file mode 100755
index 0000000..878691d
--- /dev/null
+++ b/Cpp/src/ArcscriptHelpers.h
@@ -0,0 +1,109 @@
+#pragma once
+
+#include
+#include
+#include
+#include
+#include
"
+ state->outputs.AddParagraph(paragraph_content);
+ return context->getText();
+}
+
+
+std::any ArcscriptVisitor::visitAssignment_segment(ArcscriptParser::Assignment_segmentContext *ctx) {
+ state->outputs.AddScript();
+ return visitStatement_assignment(ctx->statement_assignment());
+}
+
+std::any ArcscriptVisitor::visitFunction_call_segment(ArcscriptParser::Function_call_segmentContext *ctx) {
+ state->outputs.AddScript();
+ return visitStatement_function_call(ctx->statement_function_call());
+}
+
+std::any ArcscriptVisitor::visitConditional_section(ArcscriptParser::Conditional_sectionContext *ctx) {
+ state->outputs.AddScript();
+ ConditionalSection ifSection = std::any_cast(visitIf_section(ctx->if_section()));
+ if (ifSection.clause) {
+ state->outputs.AddScript();
+ return ifSection.script;
+ }
+ for (ArcscriptParser::Else_if_sectionContext *else_if_section : ctx->else_if_section()) {
+ ConditionalSection elif_section = std::any_cast(visitElse_if_section(else_if_section));
+ if (elif_section.clause) {
+ return elif_section.script;
+ }
+ }
+ if (ctx->else_section() != NULL) {
+ ConditionalSection elseSection = std::any_cast(visitElse_section(ctx->else_section()));
+ state->outputs.AddScript();
+ return elseSection.script;
+ }
+ state->outputs.AddScript();
+ return std::any();
+}
+
+std::any ArcscriptVisitor::visitIf_section(ArcscriptParser::If_sectionContext *ctx) {
+ Expression result = std::any_cast(visitIf_clause(ctx->if_clause()));
+ ConditionalSection ifSection;
+ ifSection.clause = false;
+ if (result == true) {
+ ifSection.clause = true;
+ ifSection.script = visitScript(ctx->script());
+ }
+ return ifSection;
+}
+
+std::any ArcscriptVisitor::visitElse_if_section(ArcscriptParser::Else_if_sectionContext *ctx) {
+ Expression result = std::any_cast(visitElse_if_clause(ctx->else_if_clause()));
+ ConditionalSection elseSection;
+ elseSection.clause = false;
+ if (result == true) {
+ elseSection.clause = true;
+ elseSection.script = visitScript(ctx->script());
+ }
+
+ return elseSection;
+}
+
+std::any ArcscriptVisitor::visitElse_section(ArcscriptParser::Else_sectionContext *ctx) {
+ ConditionalSection elseIfSection;
+ elseIfSection.clause = true;
+ elseIfSection.script = visitScript(ctx->script());
+ return elseIfSection;
+}
+
+std::any ArcscriptVisitor::visitIf_clause(ArcscriptParser::If_clauseContext *ctx) {
+ return visitCompound_condition_or(ctx->compound_condition_or());
+}
+
+std::any ArcscriptVisitor::visitElse_if_clause(ArcscriptParser::Else_if_clauseContext *ctx) {
+ return visitCompound_condition_or(ctx->compound_condition_or());
+}
+
+std::any ArcscriptVisitor::visitStatement_assignment(ArcscriptParser::Statement_assignmentContext *ctx) {
+ std::string variableName = ctx->VARIABLE()->getText();
+ Expression compound_condition_or = std::any_cast(visitCompound_condition_or(ctx->compound_condition_or()));
+ if (ctx->ASSIGN() != NULL) {
+ state->setVarValue(variableName, compound_condition_or.value);
+ return std::any();
+ }
+
+ Expression varValue;
+ varValue.setValue(state->getVarValue(variableName));
+
+ if (ctx->ASSIGNADD() != NULL) {
+ varValue += compound_condition_or;
+ }
+ if (ctx->ASSIGNSUB() != NULL) {
+ varValue -= compound_condition_or;
+ }
+ if (ctx->ASSIGNMUL() != NULL) {
+ varValue *= compound_condition_or;
+ }
+ if (ctx->ASSIGNDIV() != NULL) {
+ varValue /= compound_condition_or;
+ }
+
+ state->setVarValue(variableName, varValue.value);
+ return std::any();
+}
+
+std::any ArcscriptVisitor::visitCompound_condition_or(ArcscriptParser::Compound_condition_orContext *ctx) {
+ std::any cond_any = visitCompound_condition_and(ctx->compound_condition_and());
+ Expression compound_condition_and = std::any_cast(cond_any);
+ if (ctx->compound_condition_or() != NULL) {
+ Expression compound_condition_or = std::any_cast(visitCompound_condition_or(ctx->compound_condition_or()));
+ Expression result(compound_condition_and || compound_condition_or);
+ return result;
+ }
+ return compound_condition_and;
+}
+
+std::any ArcscriptVisitor::visitCompound_condition_and(ArcscriptParser::Compound_condition_andContext *ctx) {
+ std::any cond_any = visitNegated_unary_condition(ctx->negated_unary_condition());
+ Expression negated_unary_condition = std::any_cast(cond_any);
+ if (ctx->compound_condition_and() != NULL) {
+ Expression compound_condition_and = std::any_cast(visitCompound_condition_and(ctx->compound_condition_and()));
+ Expression result(negated_unary_condition && compound_condition_and);
+ return result;
+ }
+ return negated_unary_condition;
+}
+
+std::any ArcscriptVisitor::visitNegated_unary_condition(ArcscriptParser::Negated_unary_conditionContext *ctx) {
+ Expression unary_condition = std::any_cast(visitUnary_condition(ctx->unary_condition()));
+ if (ctx->NEG() != NULL || ctx->NOTKEYWORD() != NULL) {
+ return Expression(!unary_condition);
+ }
+ return unary_condition;
+}
+
+std::any ArcscriptVisitor::visitCondition(ArcscriptParser::ConditionContext *ctx) {
+ if (ctx->expression().size() == 1) {
+ return visitExpression(ctx->expression()[0]);
+
+ // Expression expr = std::any_cast(exprAny);
+ // if (expr.type() == typeid(double)) {
+ // return expr > 0.0;
+ // }
+ // else if (expr.type() == typeid(int)) {
+ // return expr > 0;
+ // }
+ // else if (expr.type() == typeid(std::string)) {
+ // return expr != "";
+ // }
+ // return std::any_cast(expr.value);
+ }
+
+ ArcscriptParser::Conditional_operatorContext *cond_operator_ctx = ctx->conditional_operator();
+ Expression exp0 = std::any_cast(visitExpression(ctx->expression()[0]));
+ Expression exp1 = std::any_cast(visitExpression(ctx->expression()[1]));
+ bool result = false;
+ if (cond_operator_ctx->GT() != NULL) {
+ result = exp0 > exp1;
+ }
+ else if (cond_operator_ctx->GE() != NULL) {
+ result = exp0 >= exp1;
+ }
+ else if (cond_operator_ctx->LT() != NULL) {
+ result = exp0 < exp1;
+ }
+ else if (cond_operator_ctx->LE() != NULL) {
+ result = exp0 <= exp1;
+ }
+ else if (cond_operator_ctx->EQ() != NULL) {
+ result = exp0 == exp1;
+ }
+ else if (cond_operator_ctx->NE() != NULL) {
+ result = exp0 != exp1;
+ }
+ else if (cond_operator_ctx->ISKEYWORD() != NULL) {
+ if (cond_operator_ctx->NOTKEYWORD() != NULL) {
+ result = exp0 != exp1;
+ } else {
+ result = exp0 == exp1;
+ }
+ }
+ return Expression(result);
+}
+
+std::any ArcscriptVisitor::visitExpression(ArcscriptParser::ExpressionContext *ctx) {
+ if (ctx->STRING() != NULL) {
+ std::string result = ctx->STRING()->getText();
+ result = result.substr(1, result.size() - 2);
+ return Expression(result);
+ }
+ if (ctx->BOOLEAN() != NULL) {
+ return Expression(ctx->BOOLEAN()->getText() == "true");
+ }
+
+ return visitAdditive_numeric_expression(ctx->additive_numeric_expression());
+}
+
+std::any ArcscriptVisitor::visitAdditive_numeric_expression(ArcscriptParser::Additive_numeric_expressionContext *ctx) {
+ if (ctx->additive_numeric_expression() != NULL) {
+ Expression result = std::any_cast(visitAdditive_numeric_expression(ctx->additive_numeric_expression()));
+ Expression mult_num_expr = std::any_cast(visitMultiplicative_numeric_expression(ctx->multiplicative_numeric_expression()));
+
+ if (ctx->ADD() != NULL) {
+ mult_num_expr = result + mult_num_expr;
+ }
+ else if (ctx->SUB() != NULL) {
+ mult_num_expr = result - mult_num_expr;
+ }
+ }
+ return std::any_cast(visitMultiplicative_numeric_expression(ctx->multiplicative_numeric_expression()));
+}
+
+std::any ArcscriptVisitor::visitMultiplicative_numeric_expression(ArcscriptParser::Multiplicative_numeric_expressionContext *ctx) {
+ if (ctx->multiplicative_numeric_expression() != NULL) {
+ Expression result = std::any_cast(visitMultiplicative_numeric_expression(ctx->multiplicative_numeric_expression()));
+ Expression signed_unary_num_expr = std::any_cast(visitSigned_unary_numeric_expression(ctx->signed_unary_numeric_expression()));
+
+ if (ctx->MUL() != NULL) {
+ signed_unary_num_expr = result * signed_unary_num_expr;
+ }
+ else if (ctx->DIV() != NULL) {
+ signed_unary_num_expr = result / signed_unary_num_expr;
+ }
+ }
+
+ return std::any_cast(visitSigned_unary_numeric_expression(ctx->signed_unary_numeric_expression()));
+}
+
+std::any ArcscriptVisitor::visitSigned_unary_numeric_expression(ArcscriptParser::Signed_unary_numeric_expressionContext *ctx) {
+ std::any expr_any = visitUnary_numeric_expression(ctx->unary_numeric_expression());
+ Expression unary_num_expr = std::any_cast(expr_any);
+ ArcscriptParser::SignContext *sign = ctx->sign();
+
+ if (sign != NULL) {
+ if (sign->ADD() != NULL) {
+ return unary_num_expr;
+ }
+ // Else MINUS
+ unary_num_expr = unary_num_expr * (-1);
+ }
+ return unary_num_expr;
+}
+
+std::any ArcscriptVisitor::visitUnary_numeric_expression(ArcscriptParser::Unary_numeric_expressionContext *ctx) {
+ if (ctx->FLOAT() != NULL) {
+ Expression result(std::stod(ctx->FLOAT()->getText()));
+ return result;
+ }
+ if (ctx->INTEGER() != NULL) {
+ Expression result(std::stoi(ctx->INTEGER()->getText()));
+ return result;
+ }
+ if (ctx->STRING() != NULL) {
+ std::string result = ctx->STRING()->getText();
+ result = result.substr(1, result.size() - 2);
+ return Expression(result);
+ }
+ if (ctx->BOOLEAN() != NULL) {
+ return Expression(ctx->BOOLEAN()->getText() == "true");
+ }
+ if (ctx->VARIABLE() != NULL) {
+ std::string variableName = ctx->VARIABLE()->getText();
+ std::any varValue = state->getVarValue(variableName);
+ if (varValue.type() == typeid(std::string)) {
+ Expression result(std::any_cast(varValue));
+ return result;
+ }
+ if (varValue.type() == typeid(bool)) {
+ Expression result(std::any_cast(varValue));
+ return result;
+ }
+ if (varValue.type() == typeid(int)) {
+ Expression result(std::any_cast(varValue));
+ return result;
+ }
+ if (varValue.type() == typeid(double)) {
+ Expression result(std::any_cast(varValue));
+ return result;
+ }
+ }
+ if (ctx->function_call() != NULL) {
+ std::any resultValue = visitFunction_call(ctx->function_call());
+ if (resultValue.type() == typeid(std::string)) {
+ Expression result(std::any_cast(resultValue));
+ return result;
+ }
+ if (resultValue.type() == typeid(bool)) {
+ Expression result(std::any_cast(resultValue));
+ return result;
+ }
+ if (resultValue.type() == typeid(int)) {
+ Expression result(std::any_cast(resultValue));
+ return result;
+ }
+ if (resultValue.type() == typeid(double)) {
+ Expression result(std::any_cast(resultValue));
+ return result;
+ }
+ throw Arcweave::RuntimeErrorException("Unknown result type from function call: " + ctx->function_call()->getText() + "\nType: " + resultValue.type().name());
+ }
+ return visitCompound_condition_or(ctx->compound_condition_or());
+}
+
+std::any ArcscriptVisitor::visitVoid_function_call(ArcscriptParser::Void_function_callContext *ctx) {
+ std::string fname = "";
+ std::any result;
+ if (ctx->VFNAME() != NULL) {
+ fname = ctx->VFNAME()->getText();
+ std::vector argument_list_result;
+ if (ctx->argument_list() != NULL) {
+ argument_list_result = std::any_cast>(visitArgument_list(ctx->argument_list()));
+ }
+ result = functions->Call(fname, argument_list_result);
+ }
+
+ if (ctx->VFNAMEVARS() != NULL) {
+ fname = ctx->VFNAMEVARS()->getText();
+ std::vector variable_list_result;
+
+ if (ctx->variable_list() != NULL) {
+ variable_list_result = std::any_cast>(visitVariable_list(ctx->variable_list()));
+ }
+ result = functions->Call(fname, variable_list_result);
+ }
+ // std::any result = std::invoke(functions->functions[fname], functions, argument_list_result);
+
+ return result;
+}
+
+std::any ArcscriptVisitor::visitFunction_call(ArcscriptParser::Function_callContext *ctx) {
+ std::vector argument_list_result;
+ if (ctx->argument_list() != NULL) {
+ argument_list_result = std::any_cast>(visitArgument_list(ctx->argument_list()));
+ }
+ std::string fname = ctx->FNAME()->getText();
+
+ // std::any result = std::invoke(functions->functions[fname], functions, argument_list_result);
+ std::any result = functions->Call(fname, argument_list_result);
+ return result;
+}
+
+std::any ArcscriptVisitor::visitVariable_list(ArcscriptParser::Variable_listContext *ctx) {
+ std::vector variables;
+ for (antlr4::tree::TerminalNode *variable : ctx->VARIABLE()) {
+ variables.push_back(state->getVar(variable->getText()));
+ }
+ return variables;
+}
+
+std::any ArcscriptVisitor::visitArgument_list(ArcscriptParser::Argument_listContext *ctx) {
+ std::vector arguments;
+ for (ArcscriptParser::ArgumentContext *argument : ctx->argument()) {
+ arguments.push_back(visitArgument(argument));
+ }
+ return arguments;
+}
+
+std::any ArcscriptVisitor::visitArgument(ArcscriptParser::ArgumentContext *ctx) {
+ if (ctx->STRING() != NULL) {
+ std::string result = ctx->STRING()->getText();
+ result = result.substr(1, result.size() - 2);
+ return Expression(result);
+ }
+ if (ctx->mention() != NULL) {
+ Mention mention_result = std::any_cast(visitMention(ctx->mention()));
+ return mention_result;
+ }
+
+ return visitAdditive_numeric_expression(ctx->additive_numeric_expression());
+}
+
+std::any ArcscriptVisitor::visitMention(ArcscriptParser::MentionContext *ctx) {
+ std::map attrs;
+ for (ArcscriptParser::Mention_attributesContext *attr : ctx->mention_attributes()) {
+ std::map res = std::any_cast>(visitMention_attributes(attr));
+ attrs[res["name"]] = res["value"];
+ }
+ std::string label = "";
+ if (ctx->MENTION_LABEL() != NULL) {
+ label = ctx->MENTION_LABEL()->getText();
+ }
+ Mention mention(label, attrs);
+ return mention;
+}
+
+inline bool ends_with(std::string const & value, std::string const & ending)
+{
+ if (ending.size() > value.size()) return false;
+ return std::equal(ending.rbegin(), ending.rend(), value.rbegin());
+}
+
+std::any ArcscriptVisitor::visitMention_attributes(ArcscriptParser::Mention_attributesContext *ctx) {
+ std::string name = ctx->ATTR_NAME()->getText();
+ antlr4::tree::TerminalNode *valueNode = ctx->ATTR_VALUE();
+ std::string value(name);
+
+ if (valueNode != NULL) {
+ std::string strvalue = valueNode->getText();
+ if ((strvalue.rfind("\"", 0) == 0 && ends_with(strvalue, "\"")) ||
+ strvalue.rfind("'", 0) == 0 && ends_with(strvalue, "'")) {
+
+ strvalue = strvalue.substr(1, strvalue.size() - 2);
+
+ }
+ value = strvalue;
+ }
+ return std::map { {"name", name }, {"value", value } };
+}
\ No newline at end of file
diff --git a/Cpp/src/ArcscriptVisitor.h b/Cpp/src/ArcscriptVisitor.h
new file mode 100755
index 0000000..c1e2500
--- /dev/null
+++ b/Cpp/src/ArcscriptVisitor.h
@@ -0,0 +1,52 @@
+#pragma once
+
+#include "antlr4-runtime.h"
+#include "ArcscriptParserBaseVisitor.h"
+#include "ArcscriptFunctions.h"
+
+using namespace Arcweave;
+
+class ArcscriptVisitor : public ArcscriptParserBaseVisitor {
+public:
+ struct ConditionalSection {
+ bool clause;
+ std::any script;
+ };
+
+ ArcscriptState *state;
+ ArcscriptFunctions *functions;
+
+ ArcscriptVisitor(ArcscriptState* _state) : state(_state) {
+ functions = new ArcscriptFunctions(state);
+ }
+
+ std::any visitInput(ArcscriptParser::InputContext *ctx) override;
+ std::any visitScript_section(ArcscriptParser::Script_sectionContext *ctx) override;
+ std::any visitAssignment_segment(ArcscriptParser::Assignment_segmentContext *ctx) override;
+ std::any visitFunction_call_segment(ArcscriptParser::Function_call_segmentContext * ctx) override;
+ std::any visitConditional_section(ArcscriptParser::Conditional_sectionContext *ctx) override;
+ std::any visitIf_section(ArcscriptParser::If_sectionContext *ctx) override;
+ std::any visitElse_if_section(ArcscriptParser::Else_if_sectionContext *ctx) override;
+ std::any visitElse_section(ArcscriptParser::Else_sectionContext *ctx) override;
+ std::any visitIf_clause(ArcscriptParser::If_clauseContext *ctx) override;
+ std::any visitElse_if_clause(ArcscriptParser::Else_if_clauseContext *ctx) override;
+ std::any visitStatement_assignment(ArcscriptParser::Statement_assignmentContext *ctx) override;
+ std::any visitCompound_condition_or(ArcscriptParser::Compound_condition_orContext *ctx) override;
+ std::any visitCompound_condition_and(ArcscriptParser::Compound_condition_andContext *ctx) override;
+ std::any visitNegated_unary_condition(ArcscriptParser::Negated_unary_conditionContext *ctx) override;
+ std::any visitCondition(ArcscriptParser::ConditionContext *ctx) override;
+ std::any visitExpression(ArcscriptParser::ExpressionContext *ctx) override;
+ std::any visitAdditive_numeric_expression(ArcscriptParser::Additive_numeric_expressionContext *ctx) override;
+ std::any visitMultiplicative_numeric_expression(ArcscriptParser::Multiplicative_numeric_expressionContext *ctx) override;
+ std::any visitSigned_unary_numeric_expression(ArcscriptParser::Signed_unary_numeric_expressionContext *ctx) override;
+ std::any visitUnary_numeric_expression(ArcscriptParser::Unary_numeric_expressionContext *ctx) override;
+ std::any visitVoid_function_call(ArcscriptParser::Void_function_callContext *ctx) override;
+ std::any visitFunction_call(ArcscriptParser::Function_callContext *ctx) override;
+ std::any visitVariable_list(ArcscriptParser::Variable_listContext *ctx) override;
+ std::any visitArgument_list(ArcscriptParser::Argument_listContext *ctx) override;
+ std::any visitArgument(ArcscriptParser::ArgumentContext *ctx) override;
+ std::any visitMention(ArcscriptParser::MentionContext *ctx) override;
+ std::any visitMention_attributes(ArcscriptParser::Mention_attributesContext *ctx) override;
+ std::any visitParagraph(ArcscriptParser::ParagraphContext* context) override;
+ std::any visitBlockquote(ArcscriptParser::BlockquoteContext* context) override;
+};
\ No newline at end of file
From ab8c007e37538944cdc056fe187c9998c2d0d400 Mon Sep 17 00:00:00 2001
From: Emmanouil Dermitzakis
Date: Wed, 25 Jun 2025 14:07:20 +0300
Subject: [PATCH 02/31] fix: cpp transpiler library
---
.gitignore | 2 +-
Cpp/.gitignore | 7 +-
Cpp/CMakeLists.txt | 164 ++---
Cpp/cmake/ExternalAntlr4Cpp.cmake | 352 +++++------
Cpp/cmake/FindANTLR.cmake | 246 ++++----
Cpp/cmake/antlr4-generator.cmake.in | 360 +++++------
Cpp/cmake/antlr4-runtime.cmake.in | 24 +-
Cpp/demo/ArcscriptTest.cpp | 137 +++++
Cpp/demo/tests/stringConcat.json | 132 ++++
Cpp/src/ArcscriptErrorExceptions.h | 108 ++--
Cpp/src/ArcscriptErrorListener.cpp | 24 +-
Cpp/src/ArcscriptErrorListener.h | 28 +-
Cpp/src/ArcscriptExpression.cpp | 624 +++++++++----------
Cpp/src/ArcscriptExpression.h | 162 ++---
Cpp/src/ArcscriptFunctions.cpp | 412 ++++++-------
Cpp/src/ArcscriptFunctions.h | 80 +--
Cpp/src/ArcscriptHelpers.h | 218 +++----
Cpp/src/ArcscriptOutputs.cpp | 158 ++---
Cpp/src/ArcscriptOutputs.h | 192 +++---
Cpp/src/ArcscriptParserBase.cpp | 198 +++---
Cpp/src/ArcscriptParserBase.h | 38 +-
Cpp/src/ArcscriptTranspiler.cpp | 344 +++++------
Cpp/src/ArcscriptTranspiler.h | 328 +++++-----
Cpp/src/ArcscriptVisitor.cpp | 922 ++++++++++++++--------------
Cpp/src/ArcscriptVisitor.h | 104 ++--
25 files changed, 2831 insertions(+), 2533 deletions(-)
create mode 100644 Cpp/demo/ArcscriptTest.cpp
create mode 100644 Cpp/demo/tests/stringConcat.json
diff --git a/.gitignore b/.gitignore
index 413023d..7e2e3c7 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,5 +1,5 @@
.DS_Store
-
+.idea
/grammar/**/.antlr
!/grammar/*.g4
diff --git a/Cpp/.gitignore b/Cpp/.gitignore
index 817844d..d1860aa 100644
--- a/Cpp/.gitignore
+++ b/Cpp/.gitignore
@@ -1,2 +1,7 @@
src/Generated
-build
\ No newline at end of file
+.idea
+build
+cmake-build-debug-visual-studio
+cmake-build-debug
+cmake-build-release-visual-studio
+cmake-build-release
diff --git a/Cpp/CMakeLists.txt b/Cpp/CMakeLists.txt
index 25096c9..ac74c43 100755
--- a/Cpp/CMakeLists.txt
+++ b/Cpp/CMakeLists.txt
@@ -1,70 +1,94 @@
-# minimum required CMAKE version
-CMAKE_MINIMUM_REQUIRED(VERSION 3.10 FATAL_ERROR)
-
-set(PROJECT_VERSION "0.1.0")
-project(ArcscriptTranspiler VERSION ${PROJECT_VERSION})
-
-list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake)
-message(CMAKE_CXX_COMPILER_ID=${CMAKE_CXX_COMPILER_ID})
-# compiler must be 17
-set(CMAKE_CXX_STANDARD 17)
-set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON)
-# required if linking to static library
-#add_definitions(-DANTLR4CPP_STATIC)
-
-# using /MD flag for antlr4_runtime (for Visual C++ compilers only)
-set(ANTLR4_WITH_STATIC_CRT OFF)
-
-# Specify the version of the antlr4 library needed for this project.
-# By default the latest version of antlr4 will be used. You can specify a
-# specific, stable version by setting a repository tag value or a link
-# to a zip file containing the libary source.
- set(ANTLR4_TAG 4.13.1)
-# set(ANTLR4_ZIP_REPOSITORY https://github.com/antlr/antlr4/archive/refs/tags/4.13.2.zip)
-
-# add external build for antlrcpp
-include(ExternalAntlr4Cpp)
-# add antlr4cpp artifacts to project environment
-include_directories(${ANTLR4_INCLUDE_DIRS})
-
-## set variable pointing to the antlr tool that supports C++
-## this is not required if the jar file can be found under PATH environment
-#set(ANTLR_EXECUTABLE /home/user/antlr-4.13.2-complete.jar)
-## add macros to generate ANTLR Cpp code from grammar
-#find_package(ANTLR REQUIRED)
-#
-## Call macro to add lexer and grammar to your build dependencies.
-#antlr_target(SampleGrammarLexer TLexer.g4 LEXER
-# PACKAGE antlrcpptest)
-#antlr_target(SampleGrammarParser TParser.g4 PARSER
-# PACKAGE antlrcpptest
-# DEPENDS_ANTLR SampleGrammarLexer
-# COMPILE_FLAGS -lib ${ANTLR_SampleGrammarLexer_OUTPUT_DIR})
-
-# include generated files in project environment
-#include_directories(${ANTLR_SampleGrammarLexer_OUTPUT_DIR})
-#include_directories(${ANTLR_SampleGrammarParser_OUTPUT_DIR})
-
-include_directories(src/Generated/ArcscriptLexer)
-include_directories(src/Generated/ArcscriptParser)
-include_directories(src)
-# add generated grammar to demo binary target
-#add_executable(demo main.cpp
-# src/Generated/ArcscriptLexer
-# src/Generated/ArcscriptParser)
-
-add_library(ArcscriptTranspiler SHARED)
-
-target_sources(ArcscriptTranspiler PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/src/ArcscriptTranspiler.cpp)
-
-set_target_properties(ArcscriptTranspiler PROPERTIES VERSION ${PROJECT_VERSION} SOVERSION ${PROJECT_VERSION})
-
-if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
- # For MSVC, we need to link against the shared library
- target_compile_options(ArcscriptTranspiler PRIVATE -Wall -Wextra)
-elseif(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
- # For other compilers, we can link against the static library
- target_compile_definitions(ArcscriptTranspiler PRIVATE WIN_EXPORT)
-endif()
-
-target_link_libraries(ArcscriptTranspiler antlr4_shared)
\ No newline at end of file
+# minimum required CMAKE version
+CMAKE_MINIMUM_REQUIRED(VERSION 3.10 FATAL_ERROR)
+
+set(PROJECT_VERSION "0.1.0")
+project(ArcscriptTranspiler VERSION ${PROJECT_VERSION})
+
+list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake)
+message(CMAKE_CXX_COMPILER_ID=${CMAKE_CXX_COMPILER_ID})
+# compiler must be 17
+set(CMAKE_CXX_STANDARD 17)
+set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON)
+# required if linking to static library
+#add_definitions(-DANTLR4CPP_STATIC)
+
+# using /MD flag for antlr4_runtime (for Visual C++ compilers only)
+set(ANTLR4_WITH_STATIC_CRT OFF)
+
+# Specify the version of the antlr4 library needed for this project.
+# By default the latest version of antlr4 will be used. You can specify a
+# specific, stable version by setting a repository tag value or a link
+# to a zip file containing the libary source.
+ set(ANTLR4_TAG 4.13.1)
+# set(ANTLR4_ZIP_REPOSITORY https://github.com/antlr/antlr4/archive/refs/tags/4.13.2.zip)
+
+# add external build for antlrcpp
+include(ExternalAntlr4Cpp)
+# add antlr4cpp artifacts to project environment
+include_directories(${ANTLR4_INCLUDE_DIRS})
+
+## set variable pointing to the antlr tool that supports C++
+## this is not required if the jar file can be found under PATH environment
+#set(ANTLR_EXECUTABLE /home/user/antlr-4.13.2-complete.jar)
+## add macros to generate ANTLR Cpp code from grammar
+#find_package(ANTLR REQUIRED)
+#
+## Call macro to add lexer and grammar to your build dependencies.
+#antlr_target(SampleGrammarLexer TLexer.g4 LEXER
+# PACKAGE antlrcpptest)
+#antlr_target(SampleGrammarParser TParser.g4 PARSER
+# PACKAGE antlrcpptest
+# DEPENDS_ANTLR SampleGrammarLexer
+# COMPILE_FLAGS -lib ${ANTLR_SampleGrammarLexer_OUTPUT_DIR})
+
+# include generated files in project environment
+#include_directories(${ANTLR_SampleGrammarLexer_OUTPUT_DIR})
+#include_directories(${ANTLR_SampleGrammarParser_OUTPUT_DIR})
+
+include_directories(src/Generated/ArcscriptLexer)
+include_directories(src/Generated/ArcscriptParser)
+include_directories(src)
+# add generated grammar to demo binary target
+#add_executable(demo main.cpp
+# src/Generated/ArcscriptLexer
+# src/Generated/ArcscriptParser)
+
+add_library(ArcscriptTranspiler SHARED)
+
+target_sources(ArcscriptTranspiler PRIVATE
+ ${CMAKE_CURRENT_SOURCE_DIR}/src/ArcscriptTranspiler.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/src/ArcscriptParserBase.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/src/ArcscriptVisitor.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/src/ArcscriptOutputs.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/src/ArcscriptFunctions.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/src/ArcscriptExpression.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/src/ArcscriptErrorListener.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/src/Generated/ArcscriptLexer/ArcscriptLexer.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/src/Generated/ArcscriptParser/ArcscriptParser.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/src/Generated/ArcscriptParser/ArcscriptParserBaseVisitor.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/src/Generated/ArcscriptParser/ArcscriptParserVisitor.cpp
+)
+
+target_sources(ArcscriptTranspiler PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src/ArcscriptTranspiler.h)
+
+set_target_properties(ArcscriptTranspiler PROPERTIES VERSION ${PROJECT_VERSION} SOVERSION ${PROJECT_VERSION})
+
+if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
+ # For MSVC, we need to link against the shared library
+ target_compile_options(ArcscriptTranspiler PRIVATE -Wall -Wextra)
+elseif(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
+ # For other compilers, we can link against the static library
+ target_compile_definitions(ArcscriptTranspiler PRIVATE WIN_EXPORT)
+endif()
+
+target_link_libraries(ArcscriptTranspiler PRIVATE antlr4_shared)
+
+add_executable(ArcscriptTest ${CMAKE_CURRENT_SOURCE_DIR}/demo/ArcscriptTest.cpp)
+
+include(FetchContent)
+
+FetchContent_Declare(json URL https://github.com/nlohmann/json/releases/download/v3.12.0/json.tar.xz)
+FetchContent_MakeAvailable(json)
+
+target_link_libraries(ArcscriptTest PRIVATE nlohmann_json::nlohmann_json)
+target_link_libraries(ArcscriptTest PRIVATE ArcscriptTranspiler)
diff --git a/Cpp/cmake/ExternalAntlr4Cpp.cmake b/Cpp/cmake/ExternalAntlr4Cpp.cmake
index 678bf8b..620b2c8 100755
--- a/Cpp/cmake/ExternalAntlr4Cpp.cmake
+++ b/Cpp/cmake/ExternalAntlr4Cpp.cmake
@@ -1,177 +1,177 @@
-cmake_minimum_required(VERSION 3.10)
-
-if(POLICY CMP0114)
- cmake_policy(SET CMP0114 NEW)
-endif()
-
-include(ExternalProject)
-
-set(ANTLR4_ROOT ${CMAKE_CURRENT_BINARY_DIR}/antlr4_runtime/src/antlr4_runtime)
-set(ANTLR4_INCLUDE_DIRS ${ANTLR4_ROOT}/runtime/Cpp/runtime/src)
-set(ANTLR4_GIT_REPOSITORY https://github.com/antlr/antlr4.git)
-if(NOT DEFINED ANTLR4_TAG)
- # Set to branch name to keep library updated at the cost of needing to rebuild after 'clean'
- # Set to commit hash to keep the build stable and does not need to rebuild after 'clean'
- set(ANTLR4_TAG master)
-endif()
-
-# Ensure that the include dir already exists at configure time (to avoid cmake erroring
-# on non-existent include dirs)
-file(MAKE_DIRECTORY "${ANTLR4_INCLUDE_DIRS}")
-
-if(${CMAKE_GENERATOR} MATCHES "Visual Studio.*")
- set(ANTLR4_OUTPUT_DIR ${ANTLR4_ROOT}/runtime/Cpp/runtime/$(Configuration))
-elseif(${CMAKE_GENERATOR} MATCHES "Xcode.*")
- set(ANTLR4_OUTPUT_DIR ${ANTLR4_ROOT}/runtime/Cpp/runtime/$(CONFIGURATION))
-else()
- set(ANTLR4_OUTPUT_DIR ${ANTLR4_ROOT}/runtime/Cpp/runtime)
-endif()
-
-if(MSVC)
- set(ANTLR4_STATIC_LIBRARIES
- ${ANTLR4_OUTPUT_DIR}/antlr4-runtime-static.lib)
- set(ANTLR4_SHARED_LIBRARIES
- ${ANTLR4_OUTPUT_DIR}/antlr4-runtime.lib)
- set(ANTLR4_RUNTIME_LIBRARIES
- ${ANTLR4_OUTPUT_DIR}/antlr4-runtime.dll)
-else()
- set(ANTLR4_STATIC_LIBRARIES
- ${ANTLR4_OUTPUT_DIR}/libantlr4-runtime.a)
- if(MINGW)
- set(ANTLR4_SHARED_LIBRARIES
- ${ANTLR4_OUTPUT_DIR}/libantlr4-runtime.dll.a)
- set(ANTLR4_RUNTIME_LIBRARIES
- ${ANTLR4_OUTPUT_DIR}/libantlr4-runtime.dll)
- elseif(CYGWIN)
- set(ANTLR4_SHARED_LIBRARIES
- ${ANTLR4_OUTPUT_DIR}/libantlr4-runtime.dll.a)
- set(ANTLR4_RUNTIME_LIBRARIES
- ${ANTLR4_OUTPUT_DIR}/cygantlr4-runtime-4.13.2.dll)
- elseif(APPLE)
- set(ANTLR4_RUNTIME_LIBRARIES
- ${ANTLR4_OUTPUT_DIR}/libantlr4-runtime.dylib)
- else()
- set(ANTLR4_RUNTIME_LIBRARIES
- ${ANTLR4_OUTPUT_DIR}/libantlr4-runtime.so)
- endif()
-endif()
-
-if(${CMAKE_GENERATOR} MATCHES ".* Makefiles")
- # This avoids
- # 'warning: jobserver unavailable: using -j1. Add '+' to parent make rule.'
- set(ANTLR4_BUILD_COMMAND $(MAKE))
-elseif(${CMAKE_GENERATOR} MATCHES "Visual Studio.*")
- set(ANTLR4_BUILD_COMMAND
- ${CMAKE_COMMAND}
- --build .
- --config $(Configuration)
- --target)
-elseif(${CMAKE_GENERATOR} MATCHES "Xcode.*")
- set(ANTLR4_BUILD_COMMAND
- ${CMAKE_COMMAND}
- --build .
- --config $(CONFIGURATION)
- --target)
-else()
- set(ANTLR4_BUILD_COMMAND
- ${CMAKE_COMMAND}
- --build .
- --target)
-endif()
-
-if(NOT DEFINED ANTLR4_WITH_STATIC_CRT)
- set(ANTLR4_WITH_STATIC_CRT ON)
-endif()
-
-if(ANTLR4_ZIP_REPOSITORY)
- ExternalProject_Add(
- antlr4_runtime
- PREFIX antlr4_runtime
- URL ${ANTLR4_ZIP_REPOSITORY}
- DOWNLOAD_DIR ${CMAKE_CURRENT_BINARY_DIR}
- BUILD_COMMAND ""
- BUILD_IN_SOURCE 1
- SOURCE_DIR ${ANTLR4_ROOT}
- SOURCE_SUBDIR runtime/Cpp
- CMAKE_CACHE_ARGS
- -DCMAKE_BUILD_TYPE:STRING=${CMAKE_BUILD_TYPE}
- -DWITH_STATIC_CRT:BOOL=${ANTLR4_WITH_STATIC_CRT}
- -DDISABLE_WARNINGS:BOOL=ON
- # -DCMAKE_CXX_STANDARD:STRING=17 # if desired, compile the runtime with a different C++ standard
- # -DCMAKE_CXX_STANDARD:STRING=${CMAKE_CXX_STANDARD} # alternatively, compile the runtime with the same C++ standard as the outer project
- INSTALL_COMMAND ""
- EXCLUDE_FROM_ALL 1)
-else()
- ExternalProject_Add(
- antlr4_runtime
- PREFIX antlr4_runtime
- GIT_REPOSITORY ${ANTLR4_GIT_REPOSITORY}
- GIT_TAG ${ANTLR4_TAG}
- DOWNLOAD_DIR ${CMAKE_CURRENT_BINARY_DIR}
- BUILD_COMMAND ""
- BUILD_IN_SOURCE 1
- SOURCE_DIR ${ANTLR4_ROOT}
- SOURCE_SUBDIR runtime/Cpp
- CMAKE_CACHE_ARGS
- -DCMAKE_BUILD_TYPE:STRING=${CMAKE_BUILD_TYPE}
- -DWITH_STATIC_CRT:BOOL=${ANTLR4_WITH_STATIC_CRT}
- -DDISABLE_WARNINGS:BOOL=ON
- # -DCMAKE_CXX_STANDARD:STRING=17 # if desired, compile the runtime with a different C++ standard
- # -DCMAKE_CXX_STANDARD:STRING=${CMAKE_CXX_STANDARD} # alternatively, compile the runtime with the same C++ standard as the outer project
- INSTALL_COMMAND ""
- EXCLUDE_FROM_ALL 1)
-endif()
-
-# Separate build step as rarely people want both
-set(ANTLR4_BUILD_DIR ${ANTLR4_ROOT})
-if(${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.14.0")
- # CMake 3.14 builds in above's SOURCE_SUBDIR when BUILD_IN_SOURCE is true
- set(ANTLR4_BUILD_DIR ${ANTLR4_ROOT}/runtime/Cpp)
-endif()
-
-ExternalProject_Add_Step(
- antlr4_runtime
- build_static
- COMMAND ${ANTLR4_BUILD_COMMAND} antlr4_static
- # Depend on target instead of step (a custom command)
- # to avoid running dependent steps concurrently
- DEPENDS antlr4_runtime
- BYPRODUCTS ${ANTLR4_STATIC_LIBRARIES}
- EXCLUDE_FROM_MAIN 1
- WORKING_DIRECTORY ${ANTLR4_BUILD_DIR})
-ExternalProject_Add_StepTargets(antlr4_runtime build_static)
-
-add_library(antlr4_static STATIC IMPORTED)
-add_dependencies(antlr4_static antlr4_runtime-build_static)
-set_target_properties(antlr4_static PROPERTIES
- IMPORTED_LOCATION ${ANTLR4_STATIC_LIBRARIES})
-target_include_directories(antlr4_static
- INTERFACE
- ${ANTLR4_INCLUDE_DIRS}
-)
-
-ExternalProject_Add_Step(
- antlr4_runtime
- build_shared
- COMMAND ${ANTLR4_BUILD_COMMAND} antlr4_shared
- # Depend on target instead of step (a custom command)
- # to avoid running dependent steps concurrently
- DEPENDS antlr4_runtime
- BYPRODUCTS ${ANTLR4_SHARED_LIBRARIES} ${ANTLR4_RUNTIME_LIBRARIES}
- EXCLUDE_FROM_MAIN 1
- WORKING_DIRECTORY ${ANTLR4_BUILD_DIR})
-ExternalProject_Add_StepTargets(antlr4_runtime build_shared)
-
-add_library(antlr4_shared SHARED IMPORTED)
-add_dependencies(antlr4_shared antlr4_runtime-build_shared)
-set_target_properties(antlr4_shared PROPERTIES
- IMPORTED_LOCATION ${ANTLR4_RUNTIME_LIBRARIES})
-target_include_directories(antlr4_shared
- INTERFACE
- ${ANTLR4_INCLUDE_DIRS}
-)
-
-if(ANTLR4_SHARED_LIBRARIES)
- set_target_properties(antlr4_shared PROPERTIES
- IMPORTED_IMPLIB ${ANTLR4_SHARED_LIBRARIES})
+cmake_minimum_required(VERSION 3.10)
+
+if(POLICY CMP0114)
+ cmake_policy(SET CMP0114 NEW)
+endif()
+
+include(ExternalProject)
+
+set(ANTLR4_ROOT ${CMAKE_CURRENT_BINARY_DIR}/antlr4_runtime/src/antlr4_runtime)
+set(ANTLR4_INCLUDE_DIRS ${ANTLR4_ROOT}/runtime/Cpp/runtime/src)
+set(ANTLR4_GIT_REPOSITORY https://github.com/antlr/antlr4.git)
+if(NOT DEFINED ANTLR4_TAG)
+ # Set to branch name to keep library updated at the cost of needing to rebuild after 'clean'
+ # Set to commit hash to keep the build stable and does not need to rebuild after 'clean'
+ set(ANTLR4_TAG master)
+endif()
+
+# Ensure that the include dir already exists at configure time (to avoid cmake erroring
+# on non-existent include dirs)
+file(MAKE_DIRECTORY "${ANTLR4_INCLUDE_DIRS}")
+
+if(${CMAKE_GENERATOR} MATCHES "Visual Studio.*")
+ set(ANTLR4_OUTPUT_DIR ${ANTLR4_ROOT}/runtime/Cpp/runtime/$(Configuration))
+elseif(${CMAKE_GENERATOR} MATCHES "Xcode.*")
+ set(ANTLR4_OUTPUT_DIR ${ANTLR4_ROOT}/runtime/Cpp/runtime/$(CONFIGURATION))
+else()
+ set(ANTLR4_OUTPUT_DIR ${ANTLR4_ROOT}/runtime/Cpp/runtime)
+endif()
+
+if(MSVC)
+ set(ANTLR4_STATIC_LIBRARIES
+ ${ANTLR4_OUTPUT_DIR}/antlr4-runtime-static.lib)
+ set(ANTLR4_SHARED_LIBRARIES
+ ${ANTLR4_OUTPUT_DIR}/antlr4-runtime.lib)
+ set(ANTLR4_RUNTIME_LIBRARIES
+ ${ANTLR4_OUTPUT_DIR}/antlr4-runtime.dll)
+else()
+ set(ANTLR4_STATIC_LIBRARIES
+ ${ANTLR4_OUTPUT_DIR}/libantlr4-runtime.a)
+ if(MINGW)
+ set(ANTLR4_SHARED_LIBRARIES
+ ${ANTLR4_OUTPUT_DIR}/libantlr4-runtime.dll.a)
+ set(ANTLR4_RUNTIME_LIBRARIES
+ ${ANTLR4_OUTPUT_DIR}/libantlr4-runtime.dll)
+ elseif(CYGWIN)
+ set(ANTLR4_SHARED_LIBRARIES
+ ${ANTLR4_OUTPUT_DIR}/libantlr4-runtime.dll.a)
+ set(ANTLR4_RUNTIME_LIBRARIES
+ ${ANTLR4_OUTPUT_DIR}/cygantlr4-runtime-4.13.2.dll)
+ elseif(APPLE)
+ set(ANTLR4_RUNTIME_LIBRARIES
+ ${ANTLR4_OUTPUT_DIR}/libantlr4-runtime.dylib)
+ else()
+ set(ANTLR4_RUNTIME_LIBRARIES
+ ${ANTLR4_OUTPUT_DIR}/libantlr4-runtime.so)
+ endif()
+endif()
+
+if(${CMAKE_GENERATOR} MATCHES ".* Makefiles")
+ # This avoids
+ # 'warning: jobserver unavailable: using -j1. Add '+' to parent make rule.'
+ set(ANTLR4_BUILD_COMMAND $(MAKE))
+elseif(${CMAKE_GENERATOR} MATCHES "Visual Studio.*")
+ set(ANTLR4_BUILD_COMMAND
+ ${CMAKE_COMMAND}
+ --build .
+ --config $(Configuration)
+ --target)
+elseif(${CMAKE_GENERATOR} MATCHES "Xcode.*")
+ set(ANTLR4_BUILD_COMMAND
+ ${CMAKE_COMMAND}
+ --build .
+ --config $(CONFIGURATION)
+ --target)
+else()
+ set(ANTLR4_BUILD_COMMAND
+ ${CMAKE_COMMAND}
+ --build .
+ --target)
+endif()
+
+if(NOT DEFINED ANTLR4_WITH_STATIC_CRT)
+ set(ANTLR4_WITH_STATIC_CRT ON)
+endif()
+
+if(ANTLR4_ZIP_REPOSITORY)
+ ExternalProject_Add(
+ antlr4_runtime
+ PREFIX antlr4_runtime
+ URL ${ANTLR4_ZIP_REPOSITORY}
+ DOWNLOAD_DIR ${CMAKE_CURRENT_BINARY_DIR}
+ BUILD_COMMAND ""
+ BUILD_IN_SOURCE 1
+ SOURCE_DIR ${ANTLR4_ROOT}
+ SOURCE_SUBDIR runtime/Cpp
+ CMAKE_CACHE_ARGS
+ -DCMAKE_BUILD_TYPE:STRING=${CMAKE_BUILD_TYPE}
+ -DWITH_STATIC_CRT:BOOL=${ANTLR4_WITH_STATIC_CRT}
+ -DDISABLE_WARNINGS:BOOL=ON
+ # -DCMAKE_CXX_STANDARD:STRING=17 # if desired, compile the runtime with a different C++ standard
+ # -DCMAKE_CXX_STANDARD:STRING=${CMAKE_CXX_STANDARD} # alternatively, compile the runtime with the same C++ standard as the outer project
+ INSTALL_COMMAND ""
+ EXCLUDE_FROM_ALL 1)
+else()
+ ExternalProject_Add(
+ antlr4_runtime
+ PREFIX antlr4_runtime
+ GIT_REPOSITORY ${ANTLR4_GIT_REPOSITORY}
+ GIT_TAG ${ANTLR4_TAG}
+ DOWNLOAD_DIR ${CMAKE_CURRENT_BINARY_DIR}
+ BUILD_COMMAND ""
+ BUILD_IN_SOURCE 1
+ SOURCE_DIR ${ANTLR4_ROOT}
+ SOURCE_SUBDIR runtime/Cpp
+ CMAKE_CACHE_ARGS
+ -DCMAKE_BUILD_TYPE:STRING=${CMAKE_BUILD_TYPE}
+ -DWITH_STATIC_CRT:BOOL=${ANTLR4_WITH_STATIC_CRT}
+ -DDISABLE_WARNINGS:BOOL=ON
+ # -DCMAKE_CXX_STANDARD:STRING=17 # if desired, compile the runtime with a different C++ standard
+ # -DCMAKE_CXX_STANDARD:STRING=${CMAKE_CXX_STANDARD} # alternatively, compile the runtime with the same C++ standard as the outer project
+ INSTALL_COMMAND ""
+ EXCLUDE_FROM_ALL 1)
+endif()
+
+# Separate build step as rarely people want both
+set(ANTLR4_BUILD_DIR ${ANTLR4_ROOT})
+if(${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.14.0")
+ # CMake 3.14 builds in above's SOURCE_SUBDIR when BUILD_IN_SOURCE is true
+ set(ANTLR4_BUILD_DIR ${ANTLR4_ROOT}/runtime/Cpp)
+endif()
+
+ExternalProject_Add_Step(
+ antlr4_runtime
+ build_static
+ COMMAND ${ANTLR4_BUILD_COMMAND} antlr4_static
+ # Depend on target instead of step (a custom command)
+ # to avoid running dependent steps concurrently
+ DEPENDS antlr4_runtime
+ BYPRODUCTS ${ANTLR4_STATIC_LIBRARIES}
+ EXCLUDE_FROM_MAIN 1
+ WORKING_DIRECTORY ${ANTLR4_BUILD_DIR})
+ExternalProject_Add_StepTargets(antlr4_runtime build_static)
+
+add_library(antlr4_static STATIC IMPORTED)
+add_dependencies(antlr4_static antlr4_runtime-build_static)
+set_target_properties(antlr4_static PROPERTIES
+ IMPORTED_LOCATION ${ANTLR4_STATIC_LIBRARIES})
+target_include_directories(antlr4_static
+ INTERFACE
+ ${ANTLR4_INCLUDE_DIRS}
+)
+
+ExternalProject_Add_Step(
+ antlr4_runtime
+ build_shared
+ COMMAND ${ANTLR4_BUILD_COMMAND} antlr4_shared
+ # Depend on target instead of step (a custom command)
+ # to avoid running dependent steps concurrently
+ DEPENDS antlr4_runtime
+ BYPRODUCTS ${ANTLR4_SHARED_LIBRARIES} ${ANTLR4_RUNTIME_LIBRARIES}
+ EXCLUDE_FROM_MAIN 1
+ WORKING_DIRECTORY ${ANTLR4_BUILD_DIR})
+ExternalProject_Add_StepTargets(antlr4_runtime build_shared)
+
+add_library(antlr4_shared SHARED IMPORTED)
+add_dependencies(antlr4_shared antlr4_runtime-build_shared)
+set_target_properties(antlr4_shared PROPERTIES
+ IMPORTED_LOCATION ${ANTLR4_RUNTIME_LIBRARIES})
+target_include_directories(antlr4_shared
+ INTERFACE
+ ${ANTLR4_INCLUDE_DIRS}
+)
+
+if(ANTLR4_SHARED_LIBRARIES)
+ set_target_properties(antlr4_shared PROPERTIES
+ IMPORTED_IMPLIB ${ANTLR4_SHARED_LIBRARIES})
endif()
\ No newline at end of file
diff --git a/Cpp/cmake/FindANTLR.cmake b/Cpp/cmake/FindANTLR.cmake
index 0c10d9d..77f4f7b 100755
--- a/Cpp/cmake/FindANTLR.cmake
+++ b/Cpp/cmake/FindANTLR.cmake
@@ -1,124 +1,124 @@
-find_package(Java QUIET COMPONENTS Runtime)
-
-if(NOT ANTLR_EXECUTABLE)
- find_program(ANTLR_EXECUTABLE
- NAMES antlr.jar antlr4.jar antlr-4.jar antlr-4.13.2-complete.jar)
-endif()
-
-if(ANTLR_EXECUTABLE AND Java_JAVA_EXECUTABLE)
- execute_process(
- COMMAND ${Java_JAVA_EXECUTABLE} -jar ${ANTLR_EXECUTABLE}
- OUTPUT_VARIABLE ANTLR_COMMAND_OUTPUT
- ERROR_VARIABLE ANTLR_COMMAND_ERROR
- RESULT_VARIABLE ANTLR_COMMAND_RESULT
- OUTPUT_STRIP_TRAILING_WHITESPACE)
-
- if(ANTLR_COMMAND_RESULT EQUAL 0)
- string(REGEX MATCH "Version [0-9]+(\\.[0-9]+)*" ANTLR_VERSION ${ANTLR_COMMAND_OUTPUT})
- string(REPLACE "Version " "" ANTLR_VERSION ${ANTLR_VERSION})
- else()
- message(
- SEND_ERROR
- "Command '${Java_JAVA_EXECUTABLE} -jar ${ANTLR_EXECUTABLE}' "
- "failed with the output '${ANTLR_COMMAND_ERROR}'")
- endif()
-
- macro(ANTLR_TARGET Name InputFile)
- set(ANTLR_OPTIONS LEXER PARSER LISTENER VISITOR)
- set(ANTLR_ONE_VALUE_ARGS PACKAGE OUTPUT_DIRECTORY DEPENDS_ANTLR)
- set(ANTLR_MULTI_VALUE_ARGS COMPILE_FLAGS DEPENDS)
- cmake_parse_arguments(ANTLR_TARGET
- "${ANTLR_OPTIONS}"
- "${ANTLR_ONE_VALUE_ARGS}"
- "${ANTLR_MULTI_VALUE_ARGS}"
- ${ARGN})
-
- set(ANTLR_${Name}_INPUT ${InputFile})
-
- get_filename_component(ANTLR_INPUT ${InputFile} NAME_WE)
-
- if(ANTLR_TARGET_OUTPUT_DIRECTORY)
- set(ANTLR_${Name}_OUTPUT_DIR ${ANTLR_TARGET_OUTPUT_DIRECTORY})
- else()
- set(ANTLR_${Name}_OUTPUT_DIR
- ${CMAKE_CURRENT_BINARY_DIR}/antlr4cpp_generated_src/${ANTLR_INPUT})
- endif()
-
- unset(ANTLR_${Name}_CXX_OUTPUTS)
-
- if((ANTLR_TARGET_LEXER AND NOT ANTLR_TARGET_PARSER) OR
- (ANTLR_TARGET_PARSER AND NOT ANTLR_TARGET_LEXER))
- list(APPEND ANTLR_${Name}_CXX_OUTPUTS
- ${ANTLR_${Name}_OUTPUT_DIR}/${ANTLR_INPUT}.h
- ${ANTLR_${Name}_OUTPUT_DIR}/${ANTLR_INPUT}.cpp)
- set(ANTLR_${Name}_OUTPUTS
- ${ANTLR_${Name}_OUTPUT_DIR}/${ANTLR_INPUT}.interp
- ${ANTLR_${Name}_OUTPUT_DIR}/${ANTLR_INPUT}.tokens)
- else()
- list(APPEND ANTLR_${Name}_CXX_OUTPUTS
- ${ANTLR_${Name}_OUTPUT_DIR}/${ANTLR_INPUT}Lexer.h
- ${ANTLR_${Name}_OUTPUT_DIR}/${ANTLR_INPUT}Lexer.cpp
- ${ANTLR_${Name}_OUTPUT_DIR}/${ANTLR_INPUT}Parser.h
- ${ANTLR_${Name}_OUTPUT_DIR}/${ANTLR_INPUT}Parser.cpp)
- list(APPEND ANTLR_${Name}_OUTPUTS
- ${ANTLR_${Name}_OUTPUT_DIR}/${ANTLR_INPUT}Lexer.interp
- ${ANTLR_${Name}_OUTPUT_DIR}/${ANTLR_INPUT}Lexer.tokens)
- endif()
-
- if(ANTLR_TARGET_LISTENER)
- list(APPEND ANTLR_${Name}_CXX_OUTPUTS
- ${ANTLR_${Name}_OUTPUT_DIR}/${ANTLR_INPUT}BaseListener.h
- ${ANTLR_${Name}_OUTPUT_DIR}/${ANTLR_INPUT}BaseListener.cpp
- ${ANTLR_${Name}_OUTPUT_DIR}/${ANTLR_INPUT}Listener.h
- ${ANTLR_${Name}_OUTPUT_DIR}/${ANTLR_INPUT}Listener.cpp)
- list(APPEND ANTLR_TARGET_COMPILE_FLAGS -listener)
- endif()
-
- if(ANTLR_TARGET_VISITOR)
- list(APPEND ANTLR_${Name}_CXX_OUTPUTS
- ${ANTLR_${Name}_OUTPUT_DIR}/${ANTLR_INPUT}BaseVisitor.h
- ${ANTLR_${Name}_OUTPUT_DIR}/${ANTLR_INPUT}BaseVisitor.cpp
- ${ANTLR_${Name}_OUTPUT_DIR}/${ANTLR_INPUT}Visitor.h
- ${ANTLR_${Name}_OUTPUT_DIR}/${ANTLR_INPUT}Visitor.cpp)
- list(APPEND ANTLR_TARGET_COMPILE_FLAGS -visitor)
- endif()
-
- if(ANTLR_TARGET_PACKAGE)
- list(APPEND ANTLR_TARGET_COMPILE_FLAGS -package ${ANTLR_TARGET_PACKAGE})
- endif()
-
- list(APPEND ANTLR_${Name}_OUTPUTS ${ANTLR_${Name}_CXX_OUTPUTS})
-
- if(ANTLR_TARGET_DEPENDS_ANTLR)
- if(ANTLR_${ANTLR_TARGET_DEPENDS_ANTLR}_INPUT)
- list(APPEND ANTLR_TARGET_DEPENDS
- ${ANTLR_${ANTLR_TARGET_DEPENDS_ANTLR}_INPUT})
- list(APPEND ANTLR_TARGET_DEPENDS
- ${ANTLR_${ANTLR_TARGET_DEPENDS_ANTLR}_OUTPUTS})
- else()
- message(SEND_ERROR
- "ANTLR target '${ANTLR_TARGET_DEPENDS_ANTLR}' not found")
- endif()
- endif()
-
- add_custom_command(
- OUTPUT ${ANTLR_${Name}_OUTPUTS}
- COMMAND ${Java_JAVA_EXECUTABLE} -jar ${ANTLR_EXECUTABLE}
- ${InputFile}
- -o ${ANTLR_${Name}_OUTPUT_DIR}
- -no-listener
- -Dlanguage=Cpp
- ${ANTLR_TARGET_COMPILE_FLAGS}
- DEPENDS ${InputFile}
- ${ANTLR_TARGET_DEPENDS}
- WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
- COMMENT "Building ${Name} with ANTLR ${ANTLR_VERSION}")
- endmacro(ANTLR_TARGET)
-
-endif(ANTLR_EXECUTABLE AND Java_JAVA_EXECUTABLE)
-
-include(FindPackageHandleStandardArgs)
-find_package_handle_standard_args(
- ANTLR
- REQUIRED_VARS ANTLR_EXECUTABLE Java_JAVA_EXECUTABLE
+find_package(Java QUIET COMPONENTS Runtime)
+
+if(NOT ANTLR_EXECUTABLE)
+ find_program(ANTLR_EXECUTABLE
+ NAMES antlr.jar antlr4.jar antlr-4.jar antlr-4.13.2-complete.jar)
+endif()
+
+if(ANTLR_EXECUTABLE AND Java_JAVA_EXECUTABLE)
+ execute_process(
+ COMMAND ${Java_JAVA_EXECUTABLE} -jar ${ANTLR_EXECUTABLE}
+ OUTPUT_VARIABLE ANTLR_COMMAND_OUTPUT
+ ERROR_VARIABLE ANTLR_COMMAND_ERROR
+ RESULT_VARIABLE ANTLR_COMMAND_RESULT
+ OUTPUT_STRIP_TRAILING_WHITESPACE)
+
+ if(ANTLR_COMMAND_RESULT EQUAL 0)
+ string(REGEX MATCH "Version [0-9]+(\\.[0-9]+)*" ANTLR_VERSION ${ANTLR_COMMAND_OUTPUT})
+ string(REPLACE "Version " "" ANTLR_VERSION ${ANTLR_VERSION})
+ else()
+ message(
+ SEND_ERROR
+ "Command '${Java_JAVA_EXECUTABLE} -jar ${ANTLR_EXECUTABLE}' "
+ "failed with the output '${ANTLR_COMMAND_ERROR}'")
+ endif()
+
+ macro(ANTLR_TARGET Name InputFile)
+ set(ANTLR_OPTIONS LEXER PARSER LISTENER VISITOR)
+ set(ANTLR_ONE_VALUE_ARGS PACKAGE OUTPUT_DIRECTORY DEPENDS_ANTLR)
+ set(ANTLR_MULTI_VALUE_ARGS COMPILE_FLAGS DEPENDS)
+ cmake_parse_arguments(ANTLR_TARGET
+ "${ANTLR_OPTIONS}"
+ "${ANTLR_ONE_VALUE_ARGS}"
+ "${ANTLR_MULTI_VALUE_ARGS}"
+ ${ARGN})
+
+ set(ANTLR_${Name}_INPUT ${InputFile})
+
+ get_filename_component(ANTLR_INPUT ${InputFile} NAME_WE)
+
+ if(ANTLR_TARGET_OUTPUT_DIRECTORY)
+ set(ANTLR_${Name}_OUTPUT_DIR ${ANTLR_TARGET_OUTPUT_DIRECTORY})
+ else()
+ set(ANTLR_${Name}_OUTPUT_DIR
+ ${CMAKE_CURRENT_BINARY_DIR}/antlr4cpp_generated_src/${ANTLR_INPUT})
+ endif()
+
+ unset(ANTLR_${Name}_CXX_OUTPUTS)
+
+ if((ANTLR_TARGET_LEXER AND NOT ANTLR_TARGET_PARSER) OR
+ (ANTLR_TARGET_PARSER AND NOT ANTLR_TARGET_LEXER))
+ list(APPEND ANTLR_${Name}_CXX_OUTPUTS
+ ${ANTLR_${Name}_OUTPUT_DIR}/${ANTLR_INPUT}.h
+ ${ANTLR_${Name}_OUTPUT_DIR}/${ANTLR_INPUT}.cpp)
+ set(ANTLR_${Name}_OUTPUTS
+ ${ANTLR_${Name}_OUTPUT_DIR}/${ANTLR_INPUT}.interp
+ ${ANTLR_${Name}_OUTPUT_DIR}/${ANTLR_INPUT}.tokens)
+ else()
+ list(APPEND ANTLR_${Name}_CXX_OUTPUTS
+ ${ANTLR_${Name}_OUTPUT_DIR}/${ANTLR_INPUT}Lexer.h
+ ${ANTLR_${Name}_OUTPUT_DIR}/${ANTLR_INPUT}Lexer.cpp
+ ${ANTLR_${Name}_OUTPUT_DIR}/${ANTLR_INPUT}Parser.h
+ ${ANTLR_${Name}_OUTPUT_DIR}/${ANTLR_INPUT}Parser.cpp)
+ list(APPEND ANTLR_${Name}_OUTPUTS
+ ${ANTLR_${Name}_OUTPUT_DIR}/${ANTLR_INPUT}Lexer.interp
+ ${ANTLR_${Name}_OUTPUT_DIR}/${ANTLR_INPUT}Lexer.tokens)
+ endif()
+
+ if(ANTLR_TARGET_LISTENER)
+ list(APPEND ANTLR_${Name}_CXX_OUTPUTS
+ ${ANTLR_${Name}_OUTPUT_DIR}/${ANTLR_INPUT}BaseListener.h
+ ${ANTLR_${Name}_OUTPUT_DIR}/${ANTLR_INPUT}BaseListener.cpp
+ ${ANTLR_${Name}_OUTPUT_DIR}/${ANTLR_INPUT}Listener.h
+ ${ANTLR_${Name}_OUTPUT_DIR}/${ANTLR_INPUT}Listener.cpp)
+ list(APPEND ANTLR_TARGET_COMPILE_FLAGS -listener)
+ endif()
+
+ if(ANTLR_TARGET_VISITOR)
+ list(APPEND ANTLR_${Name}_CXX_OUTPUTS
+ ${ANTLR_${Name}_OUTPUT_DIR}/${ANTLR_INPUT}BaseVisitor.h
+ ${ANTLR_${Name}_OUTPUT_DIR}/${ANTLR_INPUT}BaseVisitor.cpp
+ ${ANTLR_${Name}_OUTPUT_DIR}/${ANTLR_INPUT}Visitor.h
+ ${ANTLR_${Name}_OUTPUT_DIR}/${ANTLR_INPUT}Visitor.cpp)
+ list(APPEND ANTLR_TARGET_COMPILE_FLAGS -visitor)
+ endif()
+
+ if(ANTLR_TARGET_PACKAGE)
+ list(APPEND ANTLR_TARGET_COMPILE_FLAGS -package ${ANTLR_TARGET_PACKAGE})
+ endif()
+
+ list(APPEND ANTLR_${Name}_OUTPUTS ${ANTLR_${Name}_CXX_OUTPUTS})
+
+ if(ANTLR_TARGET_DEPENDS_ANTLR)
+ if(ANTLR_${ANTLR_TARGET_DEPENDS_ANTLR}_INPUT)
+ list(APPEND ANTLR_TARGET_DEPENDS
+ ${ANTLR_${ANTLR_TARGET_DEPENDS_ANTLR}_INPUT})
+ list(APPEND ANTLR_TARGET_DEPENDS
+ ${ANTLR_${ANTLR_TARGET_DEPENDS_ANTLR}_OUTPUTS})
+ else()
+ message(SEND_ERROR
+ "ANTLR target '${ANTLR_TARGET_DEPENDS_ANTLR}' not found")
+ endif()
+ endif()
+
+ add_custom_command(
+ OUTPUT ${ANTLR_${Name}_OUTPUTS}
+ COMMAND ${Java_JAVA_EXECUTABLE} -jar ${ANTLR_EXECUTABLE}
+ ${InputFile}
+ -o ${ANTLR_${Name}_OUTPUT_DIR}
+ -no-listener
+ -Dlanguage=Cpp
+ ${ANTLR_TARGET_COMPILE_FLAGS}
+ DEPENDS ${InputFile}
+ ${ANTLR_TARGET_DEPENDS}
+ WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
+ COMMENT "Building ${Name} with ANTLR ${ANTLR_VERSION}")
+ endmacro(ANTLR_TARGET)
+
+endif(ANTLR_EXECUTABLE AND Java_JAVA_EXECUTABLE)
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(
+ ANTLR
+ REQUIRED_VARS ANTLR_EXECUTABLE Java_JAVA_EXECUTABLE
VERSION_VAR ANTLR_VERSION)
\ No newline at end of file
diff --git a/Cpp/cmake/antlr4-generator.cmake.in b/Cpp/cmake/antlr4-generator.cmake.in
index 4cfd908..9672d58 100755
--- a/Cpp/cmake/antlr4-generator.cmake.in
+++ b/Cpp/cmake/antlr4-generator.cmake.in
@@ -1,181 +1,181 @@
-set(ANTLR_VERSION @ANTLR_VERSION@)
-
-@PACKAGE_INIT@
-
-if (NOT ANTLR4_CPP_GENERATED_SRC_DIR)
- set(ANTLR4_GENERATED_SRC_DIR ${CMAKE_BINARY_DIR}/antlr4_generated_src)
-endif()
-
-FIND_PACKAGE(Java COMPONENTS Runtime REQUIRED)
-
-#
-# The ANTLR generator will output the following files given the input file f.g4
-#
-# Input -> f.g4
-# Output -> f.h
-# -> f.cpp
-#
-# the following files will only be produced if there is a parser contained
-# Flag -visitor active
-# Output -> BaseVisitor.h
-# -> BaseVisitor.cpp
-# -> Visitor.h
-# -> Visitor.cpp
-#
-# Flag -listener active
-# Output -> BaseListener.h
-# -> BaseListener.cpp
-# -> Listener.h
-# -> Listener.cpp
-#
-# See documentation in markup
-#
-function(antlr4_generate
- Antlr4_ProjectTarget
- Antlr4_InputFile
- Antlr4_GeneratorType
- )
-
- set( Antlr4_GeneratedSrcDir ${ANTLR4_GENERATED_SRC_DIR}/${Antlr4_ProjectTarget} )
-
- get_filename_component(Antlr4_InputFileBaseName ${Antlr4_InputFile} NAME_WE )
-
- list( APPEND Antlr4_GeneratorStatusMessage "Common Include-, Source- and Tokenfiles" )
-
- if ( ${Antlr4_GeneratorType} STREQUAL "LEXER")
- set(Antlr4_LexerBaseName "${Antlr4_InputFileBaseName}")
- set(Antlr4_ParserBaseName "")
- else()
- if ( ${Antlr4_GeneratorType} STREQUAL "PARSER")
- set(Antlr4_LexerBaseName "")
- set(Antlr4_ParserBaseName "${Antlr4_InputFileBaseName}")
- else()
- if ( ${Antlr4_GeneratorType} STREQUAL "BOTH")
- set(Antlr4_LexerBaseName "${Antlr4_InputFileBaseName}Lexer")
- set(Antlr4_ParserBaseName "${Antlr4_InputFileBaseName}Parser")
- else()
- message(FATAL_ERROR "The third parameter must be LEXER, PARSER or BOTH")
- endif ()
- endif ()
- endif ()
-
- # Prepare list of generated targets
- list( APPEND Antlr4_GeneratedTargets "${Antlr4_GeneratedSrcDir}/${Antlr4_InputFileBaseName}.tokens" )
- list( APPEND Antlr4_GeneratedTargets "${Antlr4_GeneratedSrcDir}/${Antlr4_InputFileBaseName}.interp" )
- list( APPEND DependentTargets "${Antlr4_GeneratedSrcDir}/${Antlr4_InputFileBaseName}.tokens" )
-
- if ( NOT ${Antlr4_LexerBaseName} STREQUAL "" )
- list( APPEND Antlr4_GeneratedTargets "${Antlr4_GeneratedSrcDir}/${Antlr4_LexerBaseName}.h" )
- list( APPEND Antlr4_GeneratedTargets "${Antlr4_GeneratedSrcDir}/${Antlr4_LexerBaseName}.cpp" )
- endif ()
-
- if ( NOT ${Antlr4_ParserBaseName} STREQUAL "" )
- list( APPEND Antlr4_GeneratedTargets "${Antlr4_GeneratedSrcDir}/${Antlr4_ParserBaseName}.h" )
- list( APPEND Antlr4_GeneratedTargets "${Antlr4_GeneratedSrcDir}/${Antlr4_ParserBaseName}.cpp" )
- endif ()
-
- # process optional arguments ...
-
- if ( ( ARGC GREATER_EQUAL 4 ) AND ARGV3 )
- set(Antlr4_BuildListenerOption "-listener")
-
- list( APPEND Antlr4_GeneratedTargets "${Antlr4_GeneratedSrcDir}/${Antlr4_InputFileBaseName}BaseListener.h" )
- list( APPEND Antlr4_GeneratedTargets "${Antlr4_GeneratedSrcDir}/${Antlr4_InputFileBaseName}BaseListener.cpp" )
- list( APPEND Antlr4_GeneratedTargets "${Antlr4_GeneratedSrcDir}/${Antlr4_InputFileBaseName}Listener.h" )
- list( APPEND Antlr4_GeneratedTargets "${Antlr4_GeneratedSrcDir}/${Antlr4_InputFileBaseName}Listener.cpp" )
-
- list( APPEND Antlr4_GeneratorStatusMessage ", Listener Include- and Sourcefiles" )
- else()
- set(Antlr4_BuildListenerOption "-no-listener")
- endif ()
-
- if ( ( ARGC GREATER_EQUAL 5 ) AND ARGV4 )
- set(Antlr4_BuildVisitorOption "-visitor")
-
- list( APPEND Antlr4_GeneratedTargets "${Antlr4_GeneratedSrcDir}/${Antlr4_InputFileBaseName}BaseVisitor.h" )
- list( APPEND Antlr4_GeneratedTargets "${Antlr4_GeneratedSrcDir}/${Antlr4_InputFileBaseName}BaseVisitor.cpp" )
- list( APPEND Antlr4_GeneratedTargets "${Antlr4_GeneratedSrcDir}/${Antlr4_InputFileBaseName}Visitor.h" )
- list( APPEND Antlr4_GeneratedTargets "${Antlr4_GeneratedSrcDir}/${Antlr4_InputFileBaseName}Visitor.cpp" )
-
- list( APPEND Antlr4_GeneratorStatusMessage ", Visitor Include- and Sourcefiles" )
- else()
- set(Antlr4_BuildVisitorOption "-no-visitor")
- endif ()
-
- if ( (ARGC GREATER_EQUAL 6 ) AND (NOT ${ARGV5} STREQUAL "") )
- set(Antlr4_NamespaceOption "-package;${ARGV5}")
-
- list( APPEND Antlr4_GeneratorStatusMessage " in Namespace ${ARGV5}" )
- else()
- set(Antlr4_NamespaceOption "")
- endif ()
-
- if ( (ARGC GREATER_EQUAL 7 ) AND (NOT ${ARGV6} STREQUAL "") )
- set(Antlr4_AdditionalDependencies ${ARGV6})
- else()
- set(Antlr4_AdditionalDependencies "")
- endif ()
-
- if ( (ARGC GREATER_EQUAL 8 ) AND (NOT ${ARGV7} STREQUAL "") )
- set(Antlr4_LibOption "-lib;${ARGV7}")
-
- list( APPEND Antlr4_GeneratorStatusMessage " using Library ${ARGV7}" )
- else()
- set(Antlr4_LibOption "")
- endif ()
-
- if(NOT Java_FOUND)
- message(FATAL_ERROR "Java is required to process grammar or lexer files! - Use 'FIND_PACKAGE(Java COMPONENTS Runtime REQUIRED)'")
- endif()
-
- if(NOT EXISTS "${ANTLR4_JAR_LOCATION}")
- message(FATAL_ERROR "Unable to find antlr tool. ANTLR4_JAR_LOCATION:${ANTLR4_JAR_LOCATION}")
- endif()
-
- # The call to generate the files
- add_custom_command(
- OUTPUT ${Antlr4_GeneratedTargets}
- # Remove target directory
- COMMAND
- ${CMAKE_COMMAND} -E remove_directory ${Antlr4_GeneratedSrcDir}
- # Create target directory
- COMMAND
- ${CMAKE_COMMAND} -E make_directory ${Antlr4_GeneratedSrcDir}
- COMMAND
- # Generate files
- "${Java_JAVA_EXECUTABLE}" -jar "${ANTLR4_JAR_LOCATION}" -Werror -Dlanguage=Cpp ${Antlr4_BuildListenerOption} ${Antlr4_BuildVisitorOption} ${Antlr4_LibOption} ${ANTLR4_GENERATED_OPTIONS} -o "${Antlr4_GeneratedSrcDir}" ${Antlr4_NamespaceOption} "${Antlr4_InputFile}"
- WORKING_DIRECTORY "${CMAKE_BINARY_DIR}"
- MAIN_DEPENDENCY "${Antlr4_InputFile}"
- DEPENDS ${Antlr4_AdditionalDependencies}
- )
-
- # set output variables in parent scope
- set( ANTLR4_INCLUDE_DIR_${Antlr4_ProjectTarget} ${Antlr4_GeneratedSrcDir} PARENT_SCOPE)
- set( ANTLR4_SRC_FILES_${Antlr4_ProjectTarget} ${Antlr4_GeneratedTargets} PARENT_SCOPE)
- set( ANTLR4_TOKEN_FILES_${Antlr4_ProjectTarget} ${DependentTargets} PARENT_SCOPE)
- set( ANTLR4_TOKEN_DIRECTORY_${Antlr4_ProjectTarget} ${Antlr4_GeneratedSrcDir} PARENT_SCOPE)
-
- # export generated cpp files into list
- foreach(generated_file ${Antlr4_GeneratedTargets})
-
- if (NOT CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
- set_source_files_properties(
- ${generated_file}
- PROPERTIES
- COMPILE_FLAGS -Wno-overloaded-virtual
- )
- endif ()
-
- if (CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
- set_source_files_properties(
- ${generated_file}
- PROPERTIES
- COMPILE_FLAGS -wd4251
- )
- endif ()
-
- endforeach(generated_file)
-
-message(STATUS "Antlr4 ${Antlr4_ProjectTarget} - Building " ${Antlr4_GeneratorStatusMessage} )
-
+set(ANTLR_VERSION @ANTLR_VERSION@)
+
+@PACKAGE_INIT@
+
+if (NOT ANTLR4_CPP_GENERATED_SRC_DIR)
+ set(ANTLR4_GENERATED_SRC_DIR ${CMAKE_BINARY_DIR}/antlr4_generated_src)
+endif()
+
+FIND_PACKAGE(Java COMPONENTS Runtime REQUIRED)
+
+#
+# The ANTLR generator will output the following files given the input file f.g4
+#
+# Input -> f.g4
+# Output -> f.h
+# -> f.cpp
+#
+# the following files will only be produced if there is a parser contained
+# Flag -visitor active
+# Output -> BaseVisitor.h
+# -> BaseVisitor.cpp
+# -> Visitor.h
+# -> Visitor.cpp
+#
+# Flag -listener active
+# Output -> BaseListener.h
+# -> BaseListener.cpp
+# -> Listener.h
+# -> Listener.cpp
+#
+# See documentation in markup
+#
+function(antlr4_generate
+ Antlr4_ProjectTarget
+ Antlr4_InputFile
+ Antlr4_GeneratorType
+ )
+
+ set( Antlr4_GeneratedSrcDir ${ANTLR4_GENERATED_SRC_DIR}/${Antlr4_ProjectTarget} )
+
+ get_filename_component(Antlr4_InputFileBaseName ${Antlr4_InputFile} NAME_WE )
+
+ list( APPEND Antlr4_GeneratorStatusMessage "Common Include-, Source- and Tokenfiles" )
+
+ if ( ${Antlr4_GeneratorType} STREQUAL "LEXER")
+ set(Antlr4_LexerBaseName "${Antlr4_InputFileBaseName}")
+ set(Antlr4_ParserBaseName "")
+ else()
+ if ( ${Antlr4_GeneratorType} STREQUAL "PARSER")
+ set(Antlr4_LexerBaseName "")
+ set(Antlr4_ParserBaseName "${Antlr4_InputFileBaseName}")
+ else()
+ if ( ${Antlr4_GeneratorType} STREQUAL "BOTH")
+ set(Antlr4_LexerBaseName "${Antlr4_InputFileBaseName}Lexer")
+ set(Antlr4_ParserBaseName "${Antlr4_InputFileBaseName}Parser")
+ else()
+ message(FATAL_ERROR "The third parameter must be LEXER, PARSER or BOTH")
+ endif ()
+ endif ()
+ endif ()
+
+ # Prepare list of generated targets
+ list( APPEND Antlr4_GeneratedTargets "${Antlr4_GeneratedSrcDir}/${Antlr4_InputFileBaseName}.tokens" )
+ list( APPEND Antlr4_GeneratedTargets "${Antlr4_GeneratedSrcDir}/${Antlr4_InputFileBaseName}.interp" )
+ list( APPEND DependentTargets "${Antlr4_GeneratedSrcDir}/${Antlr4_InputFileBaseName}.tokens" )
+
+ if ( NOT ${Antlr4_LexerBaseName} STREQUAL "" )
+ list( APPEND Antlr4_GeneratedTargets "${Antlr4_GeneratedSrcDir}/${Antlr4_LexerBaseName}.h" )
+ list( APPEND Antlr4_GeneratedTargets "${Antlr4_GeneratedSrcDir}/${Antlr4_LexerBaseName}.cpp" )
+ endif ()
+
+ if ( NOT ${Antlr4_ParserBaseName} STREQUAL "" )
+ list( APPEND Antlr4_GeneratedTargets "${Antlr4_GeneratedSrcDir}/${Antlr4_ParserBaseName}.h" )
+ list( APPEND Antlr4_GeneratedTargets "${Antlr4_GeneratedSrcDir}/${Antlr4_ParserBaseName}.cpp" )
+ endif ()
+
+ # process optional arguments ...
+
+ if ( ( ARGC GREATER_EQUAL 4 ) AND ARGV3 )
+ set(Antlr4_BuildListenerOption "-listener")
+
+ list( APPEND Antlr4_GeneratedTargets "${Antlr4_GeneratedSrcDir}/${Antlr4_InputFileBaseName}BaseListener.h" )
+ list( APPEND Antlr4_GeneratedTargets "${Antlr4_GeneratedSrcDir}/${Antlr4_InputFileBaseName}BaseListener.cpp" )
+ list( APPEND Antlr4_GeneratedTargets "${Antlr4_GeneratedSrcDir}/${Antlr4_InputFileBaseName}Listener.h" )
+ list( APPEND Antlr4_GeneratedTargets "${Antlr4_GeneratedSrcDir}/${Antlr4_InputFileBaseName}Listener.cpp" )
+
+ list( APPEND Antlr4_GeneratorStatusMessage ", Listener Include- and Sourcefiles" )
+ else()
+ set(Antlr4_BuildListenerOption "-no-listener")
+ endif ()
+
+ if ( ( ARGC GREATER_EQUAL 5 ) AND ARGV4 )
+ set(Antlr4_BuildVisitorOption "-visitor")
+
+ list( APPEND Antlr4_GeneratedTargets "${Antlr4_GeneratedSrcDir}/${Antlr4_InputFileBaseName}BaseVisitor.h" )
+ list( APPEND Antlr4_GeneratedTargets "${Antlr4_GeneratedSrcDir}/${Antlr4_InputFileBaseName}BaseVisitor.cpp" )
+ list( APPEND Antlr4_GeneratedTargets "${Antlr4_GeneratedSrcDir}/${Antlr4_InputFileBaseName}Visitor.h" )
+ list( APPEND Antlr4_GeneratedTargets "${Antlr4_GeneratedSrcDir}/${Antlr4_InputFileBaseName}Visitor.cpp" )
+
+ list( APPEND Antlr4_GeneratorStatusMessage ", Visitor Include- and Sourcefiles" )
+ else()
+ set(Antlr4_BuildVisitorOption "-no-visitor")
+ endif ()
+
+ if ( (ARGC GREATER_EQUAL 6 ) AND (NOT ${ARGV5} STREQUAL "") )
+ set(Antlr4_NamespaceOption "-package;${ARGV5}")
+
+ list( APPEND Antlr4_GeneratorStatusMessage " in Namespace ${ARGV5}" )
+ else()
+ set(Antlr4_NamespaceOption "")
+ endif ()
+
+ if ( (ARGC GREATER_EQUAL 7 ) AND (NOT ${ARGV6} STREQUAL "") )
+ set(Antlr4_AdditionalDependencies ${ARGV6})
+ else()
+ set(Antlr4_AdditionalDependencies "")
+ endif ()
+
+ if ( (ARGC GREATER_EQUAL 8 ) AND (NOT ${ARGV7} STREQUAL "") )
+ set(Antlr4_LibOption "-lib;${ARGV7}")
+
+ list( APPEND Antlr4_GeneratorStatusMessage " using Library ${ARGV7}" )
+ else()
+ set(Antlr4_LibOption "")
+ endif ()
+
+ if(NOT Java_FOUND)
+ message(FATAL_ERROR "Java is required to process grammar or lexer files! - Use 'FIND_PACKAGE(Java COMPONENTS Runtime REQUIRED)'")
+ endif()
+
+ if(NOT EXISTS "${ANTLR4_JAR_LOCATION}")
+ message(FATAL_ERROR "Unable to find antlr tool. ANTLR4_JAR_LOCATION:${ANTLR4_JAR_LOCATION}")
+ endif()
+
+ # The call to generate the files
+ add_custom_command(
+ OUTPUT ${Antlr4_GeneratedTargets}
+ # Remove target directory
+ COMMAND
+ ${CMAKE_COMMAND} -E remove_directory ${Antlr4_GeneratedSrcDir}
+ # Create target directory
+ COMMAND
+ ${CMAKE_COMMAND} -E make_directory ${Antlr4_GeneratedSrcDir}
+ COMMAND
+ # Generate files
+ "${Java_JAVA_EXECUTABLE}" -jar "${ANTLR4_JAR_LOCATION}" -Werror -Dlanguage=Cpp ${Antlr4_BuildListenerOption} ${Antlr4_BuildVisitorOption} ${Antlr4_LibOption} ${ANTLR4_GENERATED_OPTIONS} -o "${Antlr4_GeneratedSrcDir}" ${Antlr4_NamespaceOption} "${Antlr4_InputFile}"
+ WORKING_DIRECTORY "${CMAKE_BINARY_DIR}"
+ MAIN_DEPENDENCY "${Antlr4_InputFile}"
+ DEPENDS ${Antlr4_AdditionalDependencies}
+ )
+
+ # set output variables in parent scope
+ set( ANTLR4_INCLUDE_DIR_${Antlr4_ProjectTarget} ${Antlr4_GeneratedSrcDir} PARENT_SCOPE)
+ set( ANTLR4_SRC_FILES_${Antlr4_ProjectTarget} ${Antlr4_GeneratedTargets} PARENT_SCOPE)
+ set( ANTLR4_TOKEN_FILES_${Antlr4_ProjectTarget} ${DependentTargets} PARENT_SCOPE)
+ set( ANTLR4_TOKEN_DIRECTORY_${Antlr4_ProjectTarget} ${Antlr4_GeneratedSrcDir} PARENT_SCOPE)
+
+ # export generated cpp files into list
+ foreach(generated_file ${Antlr4_GeneratedTargets})
+
+ if (NOT CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
+ set_source_files_properties(
+ ${generated_file}
+ PROPERTIES
+ COMPILE_FLAGS -Wno-overloaded-virtual
+ )
+ endif ()
+
+ if (CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
+ set_source_files_properties(
+ ${generated_file}
+ PROPERTIES
+ COMPILE_FLAGS -wd4251
+ )
+ endif ()
+
+ endforeach(generated_file)
+
+message(STATUS "Antlr4 ${Antlr4_ProjectTarget} - Building " ${Antlr4_GeneratorStatusMessage} )
+
endfunction()
\ No newline at end of file
diff --git a/Cpp/cmake/antlr4-runtime.cmake.in b/Cpp/cmake/antlr4-runtime.cmake.in
index 04f5252..c120494 100755
--- a/Cpp/cmake/antlr4-runtime.cmake.in
+++ b/Cpp/cmake/antlr4-runtime.cmake.in
@@ -1,13 +1,13 @@
-set(ANTLR_VERSION @ANTLR_VERSION@)
-
-@PACKAGE_INIT@
-
-set_and_check(ANTLR4_INCLUDE_DIR "@PACKAGE_ANTLR4_INCLUDE_DIR@")
-set_and_check(ANTLR4_LIB_DIR "@PACKAGE_ANTLR4_LIB_DIR@")
-
-include(CMakeFindDependencyMacro)
-find_dependency(Threads)
-
-include(${CMAKE_CURRENT_LIST_DIR}/@targets_export_name@.cmake)
-
+set(ANTLR_VERSION @ANTLR_VERSION@)
+
+@PACKAGE_INIT@
+
+set_and_check(ANTLR4_INCLUDE_DIR "@PACKAGE_ANTLR4_INCLUDE_DIR@")
+set_and_check(ANTLR4_LIB_DIR "@PACKAGE_ANTLR4_LIB_DIR@")
+
+include(CMakeFindDependencyMacro)
+find_dependency(Threads)
+
+include(${CMAKE_CURRENT_LIST_DIR}/@targets_export_name@.cmake)
+
check_required_components(antlr)
\ No newline at end of file
diff --git a/Cpp/demo/ArcscriptTest.cpp b/Cpp/demo/ArcscriptTest.cpp
new file mode 100644
index 0000000..f4fe411
--- /dev/null
+++ b/Cpp/demo/ArcscriptTest.cpp
@@ -0,0 +1,137 @@
+// ArcscriptTranspilerTest.cpp : This file contains the 'main' function. Program execution begins and ends there.
+//
+
+#include
+#include
+#include
+#include