mirror of
https://github.com/avinal/xeus-basic.git
synced 2026-01-10 07:08:35 +05:30
add xbasic interpreter implementation
Signed-off-by: Avinal Kumar <avinal.xlvii@gmail.com>
This commit is contained in:
3
.gitignore
vendored
3
.gitignore
vendored
@@ -1,4 +1,5 @@
|
|||||||
**/build
|
**/build
|
||||||
/.vscode
|
/.vscode
|
||||||
/cpm_modules
|
/cpm_modules
|
||||||
.DS_Store
|
.DS_Store
|
||||||
|
.idea
|
||||||
97
CMakeLists.txt
Normal file
97
CMakeLists.txt
Normal file
@@ -0,0 +1,97 @@
|
|||||||
|
cmake_minimum_required(VERSION 3.16 FATAL_ERROR)
|
||||||
|
|
||||||
|
# ---- Project ----
|
||||||
|
|
||||||
|
# Note: update this to your new project's name and version
|
||||||
|
project(xbasic VERSION 1.0 LANGUAGES CXX)
|
||||||
|
|
||||||
|
# ---- Include guards ----
|
||||||
|
|
||||||
|
if (PROJECT_SOURCE_DIR STREQUAL PROJECT_BINARY_DIR)
|
||||||
|
message(FATAL_ERROR "In-source builds not allowed.
|
||||||
|
Please make a new directory (called a build directory) and run CMake from there.")
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
set(EXECUTABLE_NAME xbasic)
|
||||||
|
|
||||||
|
# Configuration
|
||||||
|
# =============
|
||||||
|
|
||||||
|
include(GNUInstallDirs)
|
||||||
|
# We generate the kernel.json file, given the installation prefix and the executable name
|
||||||
|
configure_file(
|
||||||
|
"${CMAKE_CURRENT_SOURCE_DIR}/share/jupyter/kernels/xbasic/kernel.json.in"
|
||||||
|
"${CMAKE_CURRENT_SOURCE_DIR}/share/jupyter/kernels/xbasic/kernel.json")
|
||||||
|
|
||||||
|
option(XEUS_STATIC_DEPENDENCIES "link statically with xeus dependencies" OFF)
|
||||||
|
if (XEUS_STATIC_DEPENDENCIES)
|
||||||
|
set(xeus_target "xeus-static")
|
||||||
|
else ()
|
||||||
|
set(xeus_target "xeus")
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
# Dependencies
|
||||||
|
# ============
|
||||||
|
|
||||||
|
# Be sure to use recent versions
|
||||||
|
set(xeus_REQUIRED_VERSION 0.19.1)
|
||||||
|
set(cppzmq_REQUIRED_VERSION 4.3.0)
|
||||||
|
|
||||||
|
find_package(xeus ${xeus_REQUIRED_VERSION} REQUIRED)
|
||||||
|
find_package(cppzmq ${cppzmq_REQUIRED_VERSION} REQUIRED)
|
||||||
|
find_package(Threads)
|
||||||
|
|
||||||
|
|
||||||
|
# Flags
|
||||||
|
# =====
|
||||||
|
|
||||||
|
include(CheckCXXCompilerFlag)
|
||||||
|
|
||||||
|
if (CMAKE_CXX_COMPILER_ID MATCHES "Clang" OR CMAKE_CXX_COMPILER_ID MATCHES "GNU" OR CMAKE_CXX_COMPILER_ID MATCHES "Intel")
|
||||||
|
CHECK_CXX_COMPILER_FLAG("-std=c++17" HAS_CPP17_FLAG)
|
||||||
|
if (HAS_CPP17_FLAG)
|
||||||
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17")
|
||||||
|
else ()
|
||||||
|
message(FATAL_ERROR "Unsupported compiler -- xeus requires C++17 support!")
|
||||||
|
endif ()
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
# Target and link
|
||||||
|
# ===============
|
||||||
|
|
||||||
|
if (NOT TARGET basic)
|
||||||
|
add_subdirectory(libs/basic)
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
# My kernel executable
|
||||||
|
add_executable(${EXECUTABLE_NAME} "")
|
||||||
|
target_sources(${EXECUTABLE_NAME} PRIVATE src/main.cc src/xbasic_interpreter.cpp)
|
||||||
|
target_include_directories(${EXECUTABLE_NAME}
|
||||||
|
PRIVATE ${CMAKE_CURRENT_LIST_DIR}/include ${CMAKE_CURRENT_LIST_DIR}/libs/basic/include)
|
||||||
|
target_link_libraries(${EXECUTABLE_NAME} PRIVATE ${xeus_target} Threads::Threads basic)
|
||||||
|
|
||||||
|
if (APPLE)
|
||||||
|
set_target_properties(${EXECUTABLE_NAME} PROPERTIES MACOSX_RPATH ON)
|
||||||
|
else ()
|
||||||
|
set_target_properties(${EXECUTABLE_NAME} PROPERTIES
|
||||||
|
BUILD_WITH_INSTALL_RPATH 1
|
||||||
|
SKIP_BUILD_RPATH FALSE)
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
set_target_properties(${EXECUTABLE_NAME} PROPERTIES INSTALL_RPATH_USE_LINK_PATH TRUE)
|
||||||
|
|
||||||
|
# Installation
|
||||||
|
# ============
|
||||||
|
|
||||||
|
# Install xbasic
|
||||||
|
install(TARGETS ${EXECUTABLE_NAME}
|
||||||
|
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
|
||||||
|
|
||||||
|
# Configuration and data directories for jupyter and xbasic
|
||||||
|
set(XJUPYTER_DATA_DIR "share/jupyter" CACHE STRING "Jupyter data directory")
|
||||||
|
|
||||||
|
# Install Jupyter kernelspecs
|
||||||
|
set(xbasicSPEC_DIR ${CMAKE_CURRENT_SOURCE_DIR}/share/jupyter/kernels)
|
||||||
|
install(DIRECTORY ${xbasicSPEC_DIR}
|
||||||
|
DESTINATION ${XJUPYTER_DATA_DIR}
|
||||||
|
PATTERN "*.in" EXCLUDE)
|
||||||
40
include/xbasic/xbasic_interpreter.hpp
Normal file
40
include/xbasic/xbasic_interpreter.hpp
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
#ifndef XBASIC_INTERPRETER_HPP_
|
||||||
|
#define XBASIC_INTERPRETER_HPP_
|
||||||
|
|
||||||
|
#include "basic/basic.hpp"
|
||||||
|
#include "nlohmann/json.hpp"
|
||||||
|
#include "xeus/xinterpreter.hpp"
|
||||||
|
|
||||||
|
|
||||||
|
using xeus::xinterpreter;
|
||||||
|
namespace nl = nlohmann;
|
||||||
|
|
||||||
|
namespace xbasic {
|
||||||
|
|
||||||
|
class xbasic_interpreter : public xinterpreter {
|
||||||
|
private:
|
||||||
|
basic code_runner;
|
||||||
|
public:
|
||||||
|
xbasic_interpreter() = default;
|
||||||
|
|
||||||
|
virtual ~xbasic_interpreter() = default;
|
||||||
|
|
||||||
|
void configure_impl() override;
|
||||||
|
|
||||||
|
nl::json execute_request_impl(int execution_counter, const std::string& code, bool silent,
|
||||||
|
bool store_history, nl::json user_expressions,
|
||||||
|
bool allow_stdin) override;
|
||||||
|
|
||||||
|
nl::json complete_request_impl(const std::string& code, int cursor_pos) override;
|
||||||
|
|
||||||
|
nl::json inspect_request_impl(const std::string& code, int cursor_pos,
|
||||||
|
int detail_level) override;
|
||||||
|
|
||||||
|
nl::json is_complete_request_impl(const std::string& code) override;
|
||||||
|
nl::json kernel_info_request_impl() override;
|
||||||
|
|
||||||
|
void shutdown_request_impl() override;
|
||||||
|
};
|
||||||
|
} // namespace xbasic
|
||||||
|
|
||||||
|
#endif // XBASIC_INTERPRETER_HPP_
|
||||||
9
share/jupyter/kernels/xbasic/kernel.json
Normal file
9
share/jupyter/kernels/xbasic/kernel.json
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
"display_name": "xbasic",
|
||||||
|
"argv": [
|
||||||
|
"/home/avinal/miniconda3/envs/vkurlnel/bin/xbasic",
|
||||||
|
"-f",
|
||||||
|
"{connection_file}"
|
||||||
|
],
|
||||||
|
"language": "basic"
|
||||||
|
}
|
||||||
9
share/jupyter/kernels/xbasic/kernel.json.in
Normal file
9
share/jupyter/kernels/xbasic/kernel.json.in
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
"display_name": "xbasic",
|
||||||
|
"argv": [
|
||||||
|
"@CMAKE_INSTALL_PREFIX@/@CMAKE_INSTALL_BINDIR@/@EXECUTABLE_NAME@",
|
||||||
|
"-f",
|
||||||
|
"{connection_file}"
|
||||||
|
],
|
||||||
|
"language": "basic"
|
||||||
|
}
|
||||||
19
src/main.cc
Normal file
19
src/main.cc
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
#include <memory>
|
||||||
|
|
||||||
|
#include "xbasic/xbasic_interpreter.hpp"
|
||||||
|
#include "xeus/xkernel.hpp"
|
||||||
|
#include "xeus/xkernel_configuration.hpp"
|
||||||
|
int main(int argc, char const *argv[]) {
|
||||||
|
// Load configuration file
|
||||||
|
std::string file_name = (argc == 1) ? "connection.json" : argv[2];
|
||||||
|
xeus::xconfiguration config = xeus::load_configuration(file_name);
|
||||||
|
|
||||||
|
// Create interpreter instance
|
||||||
|
using interpreter_ptr = std::unique_ptr<xbasic::xbasic_interpreter>;
|
||||||
|
interpreter_ptr interpreter = std::make_unique<xbasic::xbasic_interpreter>();
|
||||||
|
|
||||||
|
// Create kernel instance and start it
|
||||||
|
xeus::xkernel kernel(config, xeus::get_user_name(), std::move(interpreter));
|
||||||
|
kernel.start();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
90
src/xbasic_interpreter.cpp
Normal file
90
src/xbasic_interpreter.cpp
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
#include "xbasic/xbasic_interpreter.hpp"
|
||||||
|
|
||||||
|
std::string basic::output = "";
|
||||||
|
|
||||||
|
namespace xbasic {
|
||||||
|
|
||||||
|
nl::json xbasic_interpreter::execute_request_impl(int execution_counter, const std::string &code,
|
||||||
|
bool silent, bool store_history,
|
||||||
|
nl::json user_expressions, bool allow_stdin) {
|
||||||
|
auto ok = []() {
|
||||||
|
nl::json result;
|
||||||
|
result["status"] = "ok";
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
|
||||||
|
std::vector<std::string> traceback;
|
||||||
|
auto handle_exception = [&](std::string what) {
|
||||||
|
nl::json result;
|
||||||
|
result["status"] = "error";
|
||||||
|
result["ename"] = "Error";
|
||||||
|
result["evalue"] = what;
|
||||||
|
traceback.push_back((std::string)result["ename"] + ": " + what);
|
||||||
|
publish_execution_error(result["ename"], result["evalue"], traceback);
|
||||||
|
traceback.clear();
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
|
||||||
|
nl::json pub_data;
|
||||||
|
try {
|
||||||
|
if (code_runner.evaluate_line(code)) {
|
||||||
|
pub_data["text/plain"] = code_runner.run();
|
||||||
|
code_runner.clear_output();
|
||||||
|
publish_execution_result(execution_counter, std::move(pub_data), nl::json::object());
|
||||||
|
return ok();
|
||||||
|
} else {
|
||||||
|
throw(code_runner.get_error());
|
||||||
|
}
|
||||||
|
} catch (const std::exception &err) {
|
||||||
|
return handle_exception(err.what());
|
||||||
|
}
|
||||||
|
return ok();
|
||||||
|
}
|
||||||
|
|
||||||
|
nl::json xbasic_interpreter::complete_request_impl(const std::string &code, int cursor_pos) {
|
||||||
|
nl::json result;
|
||||||
|
result["status"] = "ok";
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
nl::json xbasic_interpreter::inspect_request_impl(const std::string &code, int cursor_pos,
|
||||||
|
int detail_level) {
|
||||||
|
nl::json result;
|
||||||
|
result["status"] = "ok";
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
nl::json xbasic_interpreter::is_complete_request_impl(const std::string &code) {
|
||||||
|
nl::json result;
|
||||||
|
result["status"] = "complete";
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void xbasic_interpreter::configure_impl() {}
|
||||||
|
|
||||||
|
nl::json xbasic_interpreter::kernel_info_request_impl() {
|
||||||
|
nl::json info;
|
||||||
|
info["implementation"] = "xbasic";
|
||||||
|
info["implementation_version"] = "0.1.0";
|
||||||
|
std::string banner = R"V0G0N(
|
||||||
|
`7MM***Yy. db .M***by. `7MMF' .g8***bg.
|
||||||
|
MM Yb ;MM: ,MI `Y MM .dP' `M
|
||||||
|
`7M' `MF' MM .P ,V^MM. `MMb. MM dM' `
|
||||||
|
`VA ,V' MMooon* ,M `MM `YMMNq. MM MM
|
||||||
|
XMX MM `Y. AbmmmqMA . `MM MM MM.
|
||||||
|
,V' VA. MM ,9 A' VML Mb dM MM `Mb. .'
|
||||||
|
.AM. .MA..JMMonal.AMA. .AMMA.`*Ybmmd* .JMML. `*bMond^
|
||||||
|
|
||||||
|
xeus-basic: a Jupyter Kernel for BASIC Language
|
||||||
|
xBASIC Version: 0.1.0")V0G0N";
|
||||||
|
info["banner"] = banner;
|
||||||
|
info["language_info"]["name"] = "basic";
|
||||||
|
info["langauge_info"]["codemirror_mode"] = "vb";
|
||||||
|
info["language_info"]["version"] = "0.1.0";
|
||||||
|
info["language_info"]["mimetype"] = "text/x-vb";
|
||||||
|
info["language_info"]["file_extension"] = ".bas";
|
||||||
|
return info;
|
||||||
|
}
|
||||||
|
|
||||||
|
void xbasic_interpreter::shutdown_request_impl() {}
|
||||||
|
} // namespace xbasic
|
||||||
Reference in New Issue
Block a user