Skip to content

Instantly share code, notes, and snippets.

@ericoporto
Last active November 3, 2019 12:17
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ericoporto/a4c0e289ec1dcbc89ede46d83c87ae5b to your computer and use it in GitHub Desktop.
Save ericoporto/a4c0e289ec1dcbc89ede46d83c87ae5b to your computer and use it in GitHub Desktop.
Changes to build ags Compiler under Linux. CMakeLists.txt should go under Solutions/Compiler.Lib

Notes on how the compiler works:

  • Pre-processing is completely handled in the Editor. All the C++ includes that handle macros are orphans that aren't called: ignore those.
  • The Editor also prepares and aggregates the code snippets that make up the program. This entails writing the code for dialog scripts.
  • When all is ready, the Editor calls ccCompileText() in file ags/Compiler/script/cs_compiler.cpp . This function calls cc_compile() in ags/Compiler/script/cs_parser.cpp which does the main work.
  • ccCompileText(), above, returns a pointer to struct ccScript. This ccScript is defined in ags/Common/script/cc_script.h and contains all the results of the compiler run. So to write a standalone compiler, one only needs the data in that struct.
  • However, whenever the compiler encountes an error, it sets the global variables ccError, ccErrorLine, ccErrorString, ccErrorCallStack. Those are declared "external" in ags/Common/script/cc_error.h and defined in ags/Common/script/cc_error.cpp. This means that if ccCompileText() returns NULL, then the global variables must be inspected for the error
  • The compiler uses a symbol table for its work, and this symbol table is a global "extern" variable. The compiler refers to the symbol table by this extern variable name. This means that the compiler can't be forked: All the compiler instances would use the same symbol table and clobber each other's work.
  • The compiler currently writes the name of the script it compiles into a global variable. This variable doesn't appear to be read anywhere.

General ideas on the standalone compiler in C++:

  • Make a separate project and include the files in ags/Compiler/script into it.
  • These files will reference files in ags/Common/script; one might want to provide their own code for some of these files that fits your needs.
  • As concerns the C# code of the Editor, find and isolate the portions that do the preparation and preprocessing. Probably reference those portions as "external references" or some such.
  • Then, call ccCompileText() and get the compilation outputs in the return value (or the errors in the global variables).
  • Afterwards, write the results into the file. For that, steal more "external references" from the Editor or includes from the C++ side of AGS.
# File generated at : 17:30:59, Wed 30 Oct
# Converted Project : Compiler.Lib.vcxproj
cmake_minimum_required(VERSION 3.0.0 FATAL_ERROR)
##################### Variables ############################
# Change if you want modify path or other values #
############################################################
# Project
get_filename_component(PROJECT_DIR "${CMAKE_CURRENT_SOURCE_DIR}" ABSOLUTE)
set(DEPENDENCIES_DIR ${PROJECT_DIR}/dependencies)
set(PROJECT_NAME CompilerLib)
# Outputs
set(OUTPUT_DEBUG /.lib/)
set(OUTPUT_RELEASE /.lib/)
################# CMake Project ############################
# The main options of project #
############################################################
project(${PROJECT_NAME} CXX)
# Define Release by default.
if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE "Release")
message(STATUS "Build type not specified: Use Release by default.")
endif(NOT CMAKE_BUILD_TYPE)
############## Artefacts Output ############################
# Defines outputs , depending BUILD TYPE #
############################################################
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${PROJECT_DIR}/${OUTPUT_DEBUG}")
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${PROJECT_DIR}/${OUTPUT_DEBUG}")
set(CMAKE_EXECUTABLE_OUTPUT_DIRECTORY "${PROJECT_DIR}/${OUTPUT_DEBUG}")
else()
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${PROJECT_DIR}/${OUTPUT_RELEASE}")
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${PROJECT_DIR}/${OUTPUT_RELEASE}")
set(CMAKE_EXECUTABLE_OUTPUT_DIRECTORY "${PROJECT_DIR}/${OUTPUT_RELEASE}")
endif()
# Messages
message("${PROJECT_NAME}: MAIN PROJECT: ${CMAKE_PROJECT_NAME}")
message("${PROJECT_NAME}: CURR PROJECT: ${CMAKE_CURRENT_SOURCE_DIR}")
message("${PROJECT_NAME}: CURR BIN DIR: ${CMAKE_CURRENT_BINARY_DIR}")
############### Files & Targets ############################
# Files of project and target to build #
############################################################
include_directories("${CMAKE_CURRENT_SOURCE_DIR}/../../Common")
include_directories("${CMAKE_CURRENT_SOURCE_DIR}/../../Compiler")
# Source Files
set(SRC_FILES
../../Compiler/script/cc_compiledscript.cpp
../../Compiler/script/cc_internallist.cpp
../../Compiler/script/cc_macrotable.cpp
../../Compiler/script/cc_symboltable.cpp
../../Compiler/script/cc_treemap.cpp
../../Compiler/script/cs_compiler.cpp
../../Compiler/script/cs_parser.cpp
../../Compiler/script/cs_parser_common.cpp
../../Compiler/script/cs_prepro.cpp
)
source_group("Sources" FILES ${SRC_FILES})
# Header Files
set(HEADERS_FILES
../../Compiler/script/cc_compiledscript.h
../../Compiler/script/cc_internallist.h
../../Compiler/script/cc_macrotable.h
../../Compiler/script/cc_symboldef.h
../../Compiler/script/cc_symboltable.h
../../Compiler/script/cc_treemap.h
../../Compiler/script/cc_variablesymlist.h
../../Compiler/script/cs_compiler.h
../../Compiler/script/cs_parser.h
../../Compiler/script/cs_parser_common.h
../../Compiler/script/cs_prepro.h
)
source_group("Headers" FILES ${HEADERS_FILES})
# Add library to build.
add_library(${PROJECT_NAME} STATIC
${SRC_FILES} ${HEADERS_FILES}
)
######################### Flags ############################
# Defines Flags for Windows and Linux #
############################################################
if(NOT MSVC)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++")
endif()
endif(NOT MSVC)
# Preprocessor definitions
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
target_compile_definitions(${PROJECT_NAME} PRIVATE
-D_DEBUG
-D_LIB
# -DWINDOWS_VERSION
)
if(MSVC)
target_compile_options(${PROJECT_NAME} PRIVATE /W3 /Od /EHsc)
endif()
endif()
if(CMAKE_BUILD_TYPE STREQUAL "Release")
target_compile_definitions(${PROJECT_NAME} PRIVATE
-DNDEBUG
-D_LIB
# -DWINDOWS_VERSION
)
if(MSVC)
target_compile_options(${PROJECT_NAME} PRIVATE /W3 /GL /Oi /Gy /EHsc)
endif()
endif()
########### Link & Dependencies ############################
# Add project dependencies and Link to project #
############################################################
diff --git a/Compiler/script/cc_symboltable.h b/Compiler/script/cc_symboltable.h
index 0feaa70b..10f41c21 100644
--- a/Compiler/script/cc_symboltable.h
+++ b/Compiler/script/cc_symboltable.h
@@ -57,7 +57,7 @@ struct symbolTable {
int add(const char*); // adds new symbol, returns -1 if already exists
// TODO: why is there "friendly name" and "name", and what's the difference?
- std::string symbolTable::get_friendly_name(int idx); // inclue ptr
+ std::string get_friendly_name(int idx); // inclue ptr
const char *get_name(int idx); // gets symbol name of index
int get_type(int ii);
@@ -71,7 +71,7 @@ private:
std::vector<char *> symbolTreeNames;
int add_operator(const char*, int priority, int vcpucmd); // adds new operator
- std::string symbolTable::get_name_string(int idx);
+ std::string get_name_string(int idx);
};
diff --git a/Compiler/script/cc_treemap.cpp b/Compiler/script/cc_treemap.cpp
index d6373b3c..236fe16e 100644
--- a/Compiler/script/cc_treemap.cpp
+++ b/Compiler/script/cc_treemap.cpp
@@ -13,6 +13,7 @@
//=============================================================================
#include "cc_treemap.h"
+#include <cstring>
int ccTreeMap::findValue(const char *key) {
if (!key || strlen(key) <= 0) { return -1; }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment