Skip to content

Commit

Permalink
Re-impl it in C++ 98 for UOS (#21)
Browse files Browse the repository at this point in the history
  • Loading branch information
da-liii authored Aug 9, 2024
1 parent a7f0ab2 commit e1c2e47
Show file tree
Hide file tree
Showing 8 changed files with 115 additions and 119 deletions.
7 changes: 0 additions & 7 deletions .github/workflows/ci-debian.yml
Original file line number Diff line number Diff line change
Expand Up @@ -47,13 +47,6 @@ jobs:
${{ env.XMAKE_GLOBALDIR }}/.xmake/packages
key: ${{ runner.os }}-xrepo-${{ hashFiles('**/xmake.lua') }}

- name: cache xmake
uses: actions/cache@v3
with:
path: |
tmp/build/.build_cache
key: ${{ runner.os }}-build-qt6-${{ hashFiles('**/xmake.lua') }}

- name: config
run: xmake config -vD --policies=build.ccache -o tmp/build -m releasedbg --yes

Expand Down
9 changes: 8 additions & 1 deletion goldfish/liii/os.scm
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
(define-library (liii os)
(export
os-call os-arch os-type os-windows? os-linux? os-macos? os-temp-dir
isdir mkdir rmdir getenv getcwd listdir)
isdir mkdir rmdir getenv getcwd listdir access)
(import (scheme process-context)
(liii error))
(begin
Expand Down Expand Up @@ -46,6 +46,13 @@
(define (os-temp-dir)
(g_os-temp-dir))

(define (access path mode)
(cond ((eq? mode 'F_OK) (g_access path 0))
((eq? mode 'X_OK) (g_access path 1))
((eq? mode 'W_OK) (g_access path 2))
((eq? mode 'R_OK) (g_access path 4))
(else (error 'value-error "Allowed mode 'F_OK, 'X_OK,'W_OK, 'R_OK"))))

(define (%check-dir-andthen path f)
(cond ((not (file-exists? path))
(file-not-found-error
Expand Down
11 changes: 7 additions & 4 deletions goldfish/scheme/boot.scm
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
; 0-clause BSD
; Adapted from S7 Scheme's r7rs.scm

(define (file-exists? path)
(if (string? path)
(g_file-exists? path)
(if (not (g_access path 0)) ; F_OK
#f
(if (g_access path 4) ; R_OK
#t
(error 'permission-error (string-append "No permission: " path))))
(error 'type-error "(file-exists? path): path should be string")))

(define (delete-file path)
Expand All @@ -13,6 +14,8 @@
(error 'read-error (string-append path " does not exist"))
(g_delete-file path))))

; 0-clause BSD
; Adapted from S7 Scheme's r7rs.scm
(define-macro (define-library libname . body) ; |(lib name)| -> environment
`(define ,(symbol (object->string libname))
(with-let (sublet (unlet)
Expand Down
45 changes: 31 additions & 14 deletions src/goldfish.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,18 +16,17 @@

#include "goldfish.hpp"

#include <filesystem>
#include <iostream>
#include <sstream>
#include <stdlib.h>
#include <tbox/platform/path.h>
#include <vector>

using std::cerr;
using std::cout;
using std::endl;
using std::string;
using std::vector;
using std::filesystem::exists;
using std::filesystem::path;

using goldfish::glue_goldfish;
using goldfish::glue_liii_os;
Expand All @@ -37,7 +36,7 @@ using goldfish::glue_scheme_time;

void
display_help () {
cout << "Goldfish Scheme " << goldfish_version << " by LiiiLabs" << endl;
cout << "Goldfish Scheme " << GOLDFISH_VERSION << " by LiiiLabs" << endl;
cout << "--version\t"
<< "display version" << endl;
cout << "-e \t"
Expand All @@ -50,7 +49,7 @@ display_help () {

void
display_version () {
cout << "Goldfish Scheme " << goldfish_version << " by LiiiLabs" << endl;
cout << "Goldfish Scheme " << GOLDFISH_VERSION << " by LiiiLabs" << endl;
cout << "based on S7 Scheme " << S7_VERSION << " (" << S7_DATE << ")" << endl;
}

Expand Down Expand Up @@ -81,28 +80,46 @@ goldfish_eval_code (s7_scheme* sc, string code) {
int
main (int argc, char** argv) {
// Check if the standard library and boot.scm exists
const path gf_root= path (argv[0]).parent_path ().parent_path ();
const path gf_lib = gf_root / "goldfish";
const path gf_boot= gf_lib / "scheme" / "boot.scm";
if (!exists (gf_lib)) {
tb_char_t data_goldfish[TB_PATH_MAXN]= {0};
tb_char_t const* goldfish=
tb_path_absolute (argv[0], data_goldfish, sizeof (data_goldfish));

tb_char_t data_bin[TB_PATH_MAXN]= {0};
tb_char_t const* ret_bin=
tb_path_directory (goldfish, data_bin, sizeof (data_bin));

tb_char_t data_root[TB_PATH_MAXN]= {0};
tb_char_t const* gf_root=
tb_path_directory (ret_bin, data_root, sizeof (data_root));

tb_char_t data_lib[TB_PATH_MAXN]= {0};
tb_char_t const* gf_lib=
tb_path_absolute_to (gf_root, "goldfish", data_lib, sizeof (data_lib));

tb_char_t data_boot[TB_PATH_MAXN]= {0};
tb_char_t const* gf_boot= tb_path_absolute_to (gf_lib, "scheme/boot.scm",
data_boot, sizeof (data_boot));

if (!tb_file_access (gf_lib, TB_FILE_MODE_RO)) {
cerr << "The load path for Goldfish Scheme Standard Library does not exist"
<< endl;
exit (-1);
}
if (!exists (gf_boot)) {
if (!tb_file_access (gf_boot, TB_FILE_MODE_RO)) {
cerr << "The boot.scm for Goldfish Scheme does not exist" << endl;
exit (-1);
}
vector<string> all_args (argv, argv + argc);
for (string arg : all_args) {
command_args.push_back (arg);
int all_args_N= all_args.size ();
for (int i= 0; i < all_args_N; i++) {
command_args.push_back (all_args[i]);
}

// Init the underlying S7 Scheme and add the load_path
s7_scheme* sc;
sc= s7_init ();
s7_load (sc, gf_boot.string ().c_str ());
s7_add_to_load_path (sc, gf_lib.string ().c_str ());
s7_load (sc, gf_boot);
s7_add_to_load_path (sc, gf_lib);

// Init tbox
if (!tb_init (tb_null, tb_null)) exit (-1);
Expand Down
139 changes: 62 additions & 77 deletions src/goldfish.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,44 +14,33 @@
// under the License.
//

#include <chrono>
#include <filesystem>
#include <cstdlib>
#include <iostream>
#include <s7.h>
#include <string>
#include <tbox/platform/file.h>
#include <tbox/tbox.h>
#include <vector>

#ifdef TB_CONFIG_OS_WINDOWS
#include <io.h>
#else
#include <unistd.h>
#endif

#if !defined(_MSC_VER)
#include <errno.h>
#include <wordexp.h>
#endif

const int patch_version= 1; // Goldfish Patch Version
const int minor_version= S7_MAJOR_VERSION; // S7 Major Version
const int major_version= 17; // C++ Standard version
#define GOLDFISH_VERSION "17.10.1"
#define GOLDFISH_PATH_MAXN TB_PATH_MAXN

static auto command_args= std::vector<std::string> ();

const std::string goldfish_version=
std::to_string (major_version)
.append (".")
.append (std::to_string (minor_version))
.append (".")
.append (std::to_string (patch_version));
static std::vector<std::string> command_args= std::vector<std::string> ();

namespace goldfish {
using std::string;
using std::vector;
using std::filesystem::create_directory;
using std::filesystem::current_path;
using std::filesystem::directory_iterator;
using std::filesystem::exists;
using std::filesystem::filesystem_error;
using std::filesystem::is_directory;
using std::filesystem::path;
using std::filesystem::remove;
using std::filesystem::temp_directory_path;

inline s7_pointer
string_vector_to_s7_vector (s7_scheme* sc, vector<string> v) {
Expand All @@ -66,35 +55,13 @@ string_vector_to_s7_vector (s7_scheme* sc, vector<string> v) {
// Glues for Goldfish
static s7_pointer
f_version (s7_scheme* sc, s7_pointer args) {
return s7_make_string (sc, goldfish_version.c_str ());
}

static s7_pointer
f_file_exists (s7_scheme* sc, s7_pointer args) {
const char* path_c= s7_string (s7_car (args));
auto p = path (path_c);
bool ret = false;
try {
ret= exists (p);
} catch (filesystem_error const& ex) {
return s7_error (sc, s7_make_symbol (sc, "read-error"),
s7_make_string (sc, ex.what ()));
}
return s7_make_boolean (sc, ret);
return s7_make_string (sc, GOLDFISH_VERSION);
}

static s7_pointer
f_delete_file (s7_scheme* sc, s7_pointer args) {
const char* path_c= s7_string (s7_car (args));
auto p = path (path_c);
try {
remove (p);
} catch (filesystem_error const& ex) {
return s7_error (sc, s7_make_symbol (sc, "io-error"),
s7_make_string (sc, ex.what ()));
}

return s7_make_boolean (sc, s7_make_symbol (sc, "<#unspecified>"));
return s7_make_boolean (sc, tb_file_remove (path_c));
}

inline void
Expand All @@ -103,19 +70,13 @@ glue_goldfish (s7_scheme* sc) {

const char* s_version = "version";
const char* d_version = "(version) => string";
const char* s_file_exists= "g_file-exists?";
const char* d_file_exists= "(g_file-exists? string) => boolean";
const char* s_delete_file= "g_delete-file";
const char* d_delete_file= "(g_delete-file string) => <#unspecified>";
const char* d_delete_file= "(g_delete-file string) => boolean";

s7_define (sc, cur_env, s7_make_symbol (sc, s_version),
s7_make_typed_function (sc, s_version, f_version, 0, 0, false,
d_version, NULL));

s7_define (sc, cur_env, s7_make_symbol (sc, s_file_exists),
s7_make_typed_function (sc, s_file_exists, f_file_exists, 1, 0,
false, d_file_exists, NULL));

s7_define (sc, cur_env, s7_make_symbol (sc, s_delete_file),
s7_make_typed_function (sc, s_delete_file, f_delete_file, 1, 0,
false, d_delete_file, NULL));
Expand All @@ -124,11 +85,10 @@ glue_goldfish (s7_scheme* sc) {
// Glues for (scheme time)
static s7_pointer
f_current_second (s7_scheme* sc, s7_pointer args) {
auto now= std::chrono::system_clock::now ();
// TODO: use std::chrono::tai_clock::now() when using C++ 20
auto now_duration= now.time_since_epoch ();
double ts = std::chrono::duration<double> (now_duration).count ();
s7_double res = ts;
tb_timeval_t tp= {0};
tb_gettimeofday (&tp, tb_null);
s7_double res= (time_t) tp.tv_sec;
return s7_make_real (sc, res);
}

Expand Down Expand Up @@ -252,49 +212,69 @@ f_os_call (s7_scheme* sc, s7_pointer args) {

static s7_pointer
f_os_temp_dir (s7_scheme* sc, s7_pointer args) {
auto temp_dir_path= temp_directory_path ().string ();
const char* temp_dir = temp_dir_path.c_str ();
return s7_make_string (sc, temp_dir);
tb_char_t path[GOLDFISH_PATH_MAXN];
tb_directory_temporary (path, GOLDFISH_PATH_MAXN);
return s7_make_string (sc, path);
}

static s7_pointer
f_isdir (s7_scheme* sc, s7_pointer args) {
const char* dir_c= s7_string (s7_car (args));
return s7_make_boolean (sc, is_directory (path (dir_c)));
const char* dir_c= s7_string (s7_car (args));
tb_file_info_t info;
bool ret= false;
if (tb_file_info (dir_c, &info)) {
if (info.type == TB_FILE_TYPE_DIRECTORY) {
ret= true;
}
}
return s7_make_boolean (sc, ret);
}

static s7_pointer
f_mkdir (s7_scheme* sc, s7_pointer args) {
const char* dir_c= s7_string (s7_car (args));
path dir = path (dir_c);
bool ret = false;
try {
ret= create_directory (dir);
} catch (filesystem_error const& ex) {
return s7_error (sc, s7_make_symbol (sc, "io-error"),
s7_make_string (sc, ex.what ()));
}
return s7_make_boolean (sc, ret);
return s7_make_boolean (sc, tb_directory_create (dir_c));
}

static s7_pointer
f_getcwd (s7_scheme* sc, s7_pointer args) {
path cwd= current_path ();
return s7_make_string (sc, cwd.string ().c_str ());
tb_char_t path[GOLDFISH_PATH_MAXN];
tb_directory_current (path, GOLDFISH_PATH_MAXN);
return s7_make_string (sc, path);
}

static tb_long_t
tb_directory_walk_func (tb_char_t const* path, tb_file_info_t const* info,
tb_cpointer_t priv) {
// check
tb_assert_and_check_return_val (path && info, TB_DIRECTORY_WALK_CODE_END);

vector<string>* p_v_result= (vector<string>*) priv;
p_v_result->push_back (string (path));
return TB_DIRECTORY_WALK_CODE_CONTINUE;
}

static s7_pointer
f_listdir (s7_scheme* sc, s7_pointer args) {
const char* path_c= s7_string (s7_car (args));
path path (path_c);
vector<string> entries;
s7_pointer ret= s7_make_vector (sc, 0);
for (const auto& entry : std::filesystem::directory_iterator (path)) {
entries.push_back (entry.path ().filename ().string ());
}
tb_directory_walk (path_c, 0, tb_false, tb_directory_walk_func, &entries);
return string_vector_to_s7_vector (sc, entries);
}

static s7_pointer
f_access (s7_scheme* sc, s7_pointer args) {
const char* path_c= s7_string (s7_car (args));
int mode = s7_integer ((s7_cadr (args)));
#ifdef TB_CONFIG_OS_WINDOWS
bool ret= (_access (path_c, mode) == 0);
#else
bool ret= (access (path_c, mode) == 0);
#endif
return s7_make_boolean (sc, ret);
}

inline void
glue_liii_os (s7_scheme* sc) {
s7_pointer cur_env= s7_curlet (sc);
Expand All @@ -315,6 +295,8 @@ glue_liii_os (s7_scheme* sc) {
const char* d_listdir = "(g_listdir) => vector";
const char* s_getcwd = "g_getcwd";
const char* d_getcwd = "(g_getcwd) => string";
const char* s_access = "g_access";
const char* d_access = "(g_access string integer) => boolean";

s7_define (sc, cur_env, s7_make_symbol (sc, s_os_type),
s7_make_typed_function (sc, s_os_type, f_os_type, 0, 0, false,
Expand All @@ -340,6 +322,9 @@ glue_liii_os (s7_scheme* sc) {
s7_define (sc, cur_env, s7_make_symbol (sc, s_getcwd),
s7_make_typed_function (sc, s_getcwd, f_getcwd, 0, 0, false,
d_getcwd, NULL));
s7_define (sc, cur_env, s7_make_symbol (sc, s_access),
s7_make_typed_function (sc, s_access, f_access, 2, 0, false,
d_access, NULL));
}

static s7_pointer
Expand Down
Loading

0 comments on commit e1c2e47

Please sign in to comment.