diff --git a/CMakeLists.txt b/CMakeLists.txt index 8903f64fd..6fb2234b6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -15,6 +15,7 @@ if (ENABLE_VCPKG) endif(ENABLE_VCPKG) option(BUILD_CLI "Build the CLI" ON) +option(EXEC_RELOCATE "Relocate the executable to the root dir" ON) add_subdirectory(src) diff --git a/docs/docs/standard-lib/argparse.md b/docs/docs/standard-lib/argparse.md index 89f3feeec..a6a96bc8a 100644 --- a/docs/docs/standard-lib/argparse.md +++ b/docs/docs/standard-lib/argparse.md @@ -20,7 +20,7 @@ parent: Standard Library To make use of the Argparse module an import is required. -```cs +```js from Argparse import Parser; ``` @@ -36,7 +36,7 @@ const parser = Parser("prog_name", "Program to do all the things"); const parser = Parser("prog_name", "Program to do all the things", "User defined usage string"); ``` -### Parse.addString(String, String, Bool, string -> Optional) +### Parser.addString(String, String, Bool, string -> Optional) To add a new string argument, call the method below with at least the 3 required arguments; name, description, and boolean indicating the flag is required. A fourth argument can be passed to give the parser a custom name for the given flag. diff --git a/docs/docs/standard-lib/bigint.md b/docs/docs/standard-lib/bigint.md index 31f86796c..20ba0ed64 100644 --- a/docs/docs/standard-lib/bigint.md +++ b/docs/docs/standard-lib/bigint.md @@ -20,7 +20,7 @@ parent: Standard Library To make use of the BigInt module an import is required. -```cs +```js import BigInt; ``` diff --git a/docs/docs/standard-lib/datetime.md b/docs/docs/standard-lib/datetime.md index 2e27c3ad9..ca7b2a1bf 100644 --- a/docs/docs/standard-lib/datetime.md +++ b/docs/docs/standard-lib/datetime.md @@ -20,7 +20,7 @@ parent: Standard Library To make use of the Datetime module an import is required. -```cs +```js import Datetime; ``` diff --git a/docs/docs/standard-lib/http.md b/docs/docs/standard-lib/http.md index a742109b7..cf1e1772e 100644 --- a/docs/docs/standard-lib/http.md +++ b/docs/docs/standard-lib/http.md @@ -20,7 +20,7 @@ parent: Standard Library To make use of the HTTP module an import is required. Along with the methods described below, this module also defines constants representing all standard response codes and their associated messages, the standard set of HTTP methods, and common request headers and values. -```cs +```js import HTTP; ``` diff --git a/docs/docs/standard-lib/io.md b/docs/docs/standard-lib/io.md index c0c0f3f58..0d35455f0 100644 --- a/docs/docs/standard-lib/io.md +++ b/docs/docs/standard-lib/io.md @@ -20,7 +20,7 @@ parent: Standard Library To make use of the IO module an import is required. -```cs +```js import IO; ``` @@ -48,6 +48,25 @@ IO.println("Dictu!"); // Dictu! ``` +### IO.eprint(...values) -> Nil + +Prints a given list of values to stderr. + +```cs +IO.eprint(0); +// 0 +``` + +### IO.eprintln(...values) -> Nil + +Prints a given list of values to stderr with an appended newline character. + +```cs +IO.eprintln("Dictu!"); +// Dictu! +``` + + ### IO.copyFile(String: src, String: dst) -> Result\ Copies the contents from the source file to the destination file. diff --git a/docs/docs/standard-lib/json.md b/docs/docs/standard-lib/json.md index 4a76e8681..718cbf131 100644 --- a/docs/docs/standard-lib/json.md +++ b/docs/docs/standard-lib/json.md @@ -20,7 +20,7 @@ parent: Standard Library To make use of the JSON module an import is required. -```cs +```js import JSON; ``` diff --git a/docs/docs/standard-lib/log.md b/docs/docs/standard-lib/log.md index 9c23fe4a5..39a71ce71 100644 --- a/docs/docs/standard-lib/log.md +++ b/docs/docs/standard-lib/log.md @@ -20,7 +20,7 @@ parent: Standard Library To make use of the Log module an import is required. -```cs +```js import Log; ``` diff --git a/docs/docs/standard-lib/math.md b/docs/docs/standard-lib/math.md index 81baa7ee6..c47289c37 100644 --- a/docs/docs/standard-lib/math.md +++ b/docs/docs/standard-lib/math.md @@ -21,7 +21,7 @@ parent: Standard Library To make use of the Math module an import is required. For the purpose of the documentation, an iterable is either a list, or passing multiple arguments to the function directly. -```cs +```js import Math; ``` diff --git a/docs/docs/standard-lib/net.md b/docs/docs/standard-lib/net.md index ec6f1a1f4..9f88b2ad3 100644 --- a/docs/docs/standard-lib/net.md +++ b/docs/docs/standard-lib/net.md @@ -20,7 +20,7 @@ parent: Standard Library To make use of the Net module an import is required. -```cs +```js import Net; ``` diff --git a/docs/docs/standard-lib/object.md b/docs/docs/standard-lib/object.md index 2c3522ff4..a2af2ef39 100644 --- a/docs/docs/standard-lib/object.md +++ b/docs/docs/standard-lib/object.md @@ -20,7 +20,7 @@ parent: Standard Library To make use of the Object module an import is required. -```cs +```js import Object; ``` diff --git a/docs/docs/standard-lib/path.md b/docs/docs/standard-lib/path.md index 29d6f9692..175a23470 100644 --- a/docs/docs/standard-lib/path.md +++ b/docs/docs/standard-lib/path.md @@ -20,7 +20,7 @@ parent: Standard Library To make use of the Path module an import is required. -```cs +```js import Path; ``` @@ -87,8 +87,6 @@ Path.exists("some/path/to/a/file.du"); // true Checks whether a given path points to a directory or not. -**Note:** This is not available on windows systems. - ```cs Path.isDir("/usr/bin/"); //true ``` diff --git a/docs/docs/standard-lib/process.md b/docs/docs/standard-lib/process.md index 69e99ef20..825317dc5 100644 --- a/docs/docs/standard-lib/process.md +++ b/docs/docs/standard-lib/process.md @@ -20,7 +20,7 @@ parent: Standard Library To make use of the Process module an import is required. -```cs +```js import Process; ``` diff --git a/docs/docs/standard-lib/queue.md b/docs/docs/standard-lib/queue.md index b724391dc..cccc3ce70 100644 --- a/docs/docs/standard-lib/queue.md +++ b/docs/docs/standard-lib/queue.md @@ -20,7 +20,7 @@ parent: Standard Library To make use of the Queue module an import is required. -```cs +```js import Queue; ``` diff --git a/docs/docs/standard-lib/socket.md b/docs/docs/standard-lib/socket.md index 888dda578..ba543c747 100644 --- a/docs/docs/standard-lib/socket.md +++ b/docs/docs/standard-lib/socket.md @@ -20,7 +20,7 @@ parent: Standard Library To make use of the Socket module an import is required. -```cs +```js import Socket; ``` diff --git a/docs/docs/standard-lib/stack.md b/docs/docs/standard-lib/stack.md index 022a906f4..c60460d8f 100644 --- a/docs/docs/standard-lib/stack.md +++ b/docs/docs/standard-lib/stack.md @@ -20,7 +20,7 @@ parent: Standard Library To make use of the Stack module an import is required. -```cs +```js import Stack; ``` diff --git a/docs/docs/standard-lib/system.md b/docs/docs/standard-lib/system.md index 66f5a30be..f282547ff 100644 --- a/docs/docs/standard-lib/system.md +++ b/docs/docs/standard-lib/system.md @@ -28,8 +28,8 @@ import System; | Constant | Description | | --------------- | ------------------------------------------------------------------------------------------------- | | System.argv | The list of command line arguments. The first element of the argv list is always the script name. | -| System.platform | This string identifies the underlying system platform. | -| System.arch | This string identifies the underlying process architecture. | +| System.platform | This string identifies the underlying system platform(common: `windows`, `linux`, `darwin`). | +| System.arch | This string identifies the underlying process architecture. | | System.version | Dictionary containing Dictu major, minor and patch versions. | | System.S_IRWXU | Read, write, and execute by owner. | | System.S_IRUSR | Read by owner. | @@ -212,7 +212,7 @@ System.clock(); ### System.time() -> Number -Returns UNIX timestamp as a number. +Returns UNIX timestamp in seconds as a number. ```cs System.time(); diff --git a/docs/docs/standard-lib/term.md b/docs/docs/standard-lib/term.md index 0b2cb43c9..99be8a806 100644 --- a/docs/docs/standard-lib/term.md +++ b/docs/docs/standard-lib/term.md @@ -20,7 +20,7 @@ parent: Standard Library To make use of the Term module an import is required. -```cs +```js import Term; ``` diff --git a/docs/docs/standard-lib/uuid.md b/docs/docs/standard-lib/uuid.md index 3cc5d120a..180de3dd4 100644 --- a/docs/docs/standard-lib/uuid.md +++ b/docs/docs/standard-lib/uuid.md @@ -20,7 +20,7 @@ parent: Standard Library To make use of the UUID module an import is required. -```cs +```js import UUID; ``` diff --git a/ops/checkTests.du b/ops/checkTests.du index d9288ec38..d7f102a31 100644 --- a/ops/checkTests.du +++ b/ops/checkTests.du @@ -23,9 +23,6 @@ const ignored = { 'range.du', 'select.du', ], - 'ffi': [ - 'libs', - ], '*': [ 'import.du', ] diff --git a/src/cli/CMakeLists.txt b/src/cli/CMakeLists.txt index 5ed8e89b0..9aa9b513a 100644 --- a/src/cli/CMakeLists.txt +++ b/src/cli/CMakeLists.txt @@ -1,12 +1,24 @@ set(DICTU_CLI_SRC main.c linenoise/linenoise.c linenoise/linenoise.h linenoise/stringbuf.c linenoise/stringbuf.h linenoise/utf8.c linenoise/utf8.h) +if(EXEC_RELOCATE) SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}) - +endif() if(NOT WIN32) list(FILTER DICTU_CLI_SRC EXCLUDE REGEX "linenoise-win32.c") endif() add_compile_definitions(USE_UTF8) add_executable(dictu ${DICTU_CLI_SRC}) + execute_process( + COMMAND git log -1 --format=%H + WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR} + OUTPUT_VARIABLE GIT_HASH + OUTPUT_STRIP_TRAILING_WHITESPACE +) +add_compile_definitions(GIT_HASH="${GIT_HASH}") +if(CMAKE_BUILD_TYPE MATCHES Debug) + add_compile_definitions(DEBUG DEBUG_STRESS_GC DEBUG_FINAL_MEM) +endif() + target_include_directories(dictu PUBLIC ${INCLUDE_DIR}) target_link_libraries(dictu dictu_api_static) if(LINUX AND CMAKE_C_COMPILER_ID STREQUAL "Clang") diff --git a/src/include/dictu_include.h b/src/include/dictu_include.h index 273ff8bad..9587f3f46 100644 --- a/src/include/dictu_include.h +++ b/src/include/dictu_include.h @@ -7,7 +7,25 @@ #define DICTU_MINOR_VERSION "30" #define DICTU_PATCH_VERSION "0" -#define DICTU_STRING_VERSION "Dictu Version: " DICTU_MAJOR_VERSION "." DICTU_MINOR_VERSION "." DICTU_PATCH_VERSION "\n" +#ifdef DEBUG + +#define DICTU_DEBUG_VERSION_STR "(Debug)" + +#else + +#define DICTU_DEBUG_VERSION_STR "" + +#endif + +#if defined(GIT_HASH) + +#define DICTU_STRING_VERSION DICTU_DEBUG_VERSION_STR "Dictu Version: " DICTU_MAJOR_VERSION "." DICTU_MINOR_VERSION "." DICTU_PATCH_VERSION " [rev: " GIT_HASH "]\n" + +#else + +#define DICTU_STRING_VERSION DICTU_DEBUG_VERSION_STR "Dictu Version: " DICTU_MAJOR_VERSION "." DICTU_MINOR_VERSION "." DICTU_PATCH_VERSION "\n" + +#endif typedef struct _vm DictuVM; diff --git a/src/optionals/ffi/ffi.c b/src/optionals/ffi.c similarity index 100% rename from src/optionals/ffi/ffi.c rename to src/optionals/ffi.c diff --git a/src/optionals/ffi/ffi.h b/src/optionals/ffi.h similarity index 91% rename from src/optionals/ffi/ffi.h rename to src/optionals/ffi.h index 7b1de9648..5b6d4f2a9 100644 --- a/src/optionals/ffi/ffi.h +++ b/src/optionals/ffi.h @@ -3,8 +3,8 @@ #include -#include "../optionals.h" -#include "../../vm/vm.h" +#include "optionals.h" +#include "../vm/vm.h" #ifdef _WIN32 #define LIB_EXTENSION ".dll" diff --git a/src/optionals/io.c b/src/optionals/io.c index 1602c7d49..630d2511b 100644 --- a/src/optionals/io.c +++ b/src/optionals/io.c @@ -38,6 +38,34 @@ static Value printlnIO(DictuVM *vm, int argCount, Value *args) { return NIL_VAL; } + +static Value printErrIO(DictuVM *vm, int argCount, Value *args) { + if (argCount == 0) { + runtimeError(vm, "printErr() takes 1 or more arguments (%d given)", argCount); + return EMPTY_VAL; + } + + for (int i = 0; i < argCount; ++i) { + printValueError(args[i]); + } + + return NIL_VAL; +} + +static Value printErrlnIO(DictuVM *vm, int argCount, Value *args) { + if (argCount == 0) { + runtimeError(vm, "printErrLn() takes 1 or more arguments (%d given)", argCount); + return EMPTY_VAL; + } + + for (int i = 0; i < argCount; ++i) { + printValueError(args[i]); + fprintf(stderr, "\n"); + } + + return NIL_VAL; +} + #ifdef _WIN32 static Value copyFileIO(DictuVM *vm, int argCount, Value *args) { if (argCount != 2) { @@ -138,6 +166,8 @@ Value createIOModule(DictuVM *vm) { */ defineNative(vm, &module->values, "print", printIO); defineNative(vm, &module->values, "println", printlnIO); + defineNative(vm, &module->values, "eprint", printErrIO); + defineNative(vm, &module->values, "eprintln", printErrlnIO); defineNative(vm, &module->values, "copyFile", copyFileIO); pop(vm); diff --git a/src/optionals/optionals.c b/src/optionals/optionals.c index f2fbe8110..7d39fab35 100644 --- a/src/optionals/optionals.c +++ b/src/optionals/optionals.c @@ -1,5 +1,4 @@ #include "optionals.h" -#include "ffi/ffi.h" BuiltinModules modules[] = { {"Argparse", &createArgParseModule, false}, diff --git a/src/optionals/optionals.h b/src/optionals/optionals.h index 70bcae938..af96f87c3 100644 --- a/src/optionals/optionals.h +++ b/src/optionals/optionals.h @@ -29,7 +29,7 @@ #include "object/object.h" #include "buffer.h" #include "unittest/unittest.h" -#include "ffi/ffi.h" +#include "ffi.h" typedef Value (*BuiltinModule)(DictuVM *vm); diff --git a/src/optionals/system.c b/src/optionals/system.c index 9a17a8b37..fa5e664cb 100644 --- a/src/optionals/system.c +++ b/src/optionals/system.c @@ -1,4 +1,5 @@ #include "system.h" +#include "../vm/utf8.h" #ifdef _WIN32 #define rmdir(DIRNAME) _rmdir(DIRNAME) @@ -268,7 +269,7 @@ static Value mkdirAllNative(DictuVM *vm, int argCount, Value *args) { return EMPTY_VAL; } - char *dir = AS_CSTRING(args[0]); + ObjString *dir = AS_STRING(args[0]); int mode = 0777; @@ -280,34 +281,30 @@ static Value mkdirAllNative(DictuVM *vm, int argCount, Value *args) { mode = AS_NUMBER(args[1]); } - - char tmp[256]; - char *p = NULL; - size_t len; - - snprintf(tmp, sizeof(tmp), "%s", dir); - - len = strlen(tmp); - if (tmp[len - 1] == '/' || tmp[len - 1] == '\\') { - tmp[len - 1] = 0; - } - int retval; - - for (p = tmp + 1; *p; p++) { - if (*p == '/' || *p == '\\') { - *p = 0; - - retval = MKDIR(tmp, mode); - if (retval < 0) { - ERROR_RESULT; + bool lastSeperator = false; + int byteOffset = 0; + char* ptr = dir->chars; + for(int i = 0; i < dir->character_len; i++) { + utf8_int32_t cp; + char *n = utf8codepoint(ptr, &cp); + if(cp == '/' || cp == '\\') { + if(byteOffset > 0){ + dir->chars[byteOffset] = '\0'; + retval = MKDIR(dir->chars, mode); + dir->chars[byteOffset] = cp; } - - *p = '/'; + lastSeperator = true; + } else { + lastSeperator = false; } + ptr = n; + byteOffset += utf8codepointsize(cp); } - - retval = MKDIR(tmp, mode); + if(!lastSeperator){ + retval = MKDIR(dir->chars, mode); + } + if (retval < 0) { ERROR_RESULT; } diff --git a/tests/path/isDir.du b/tests/path/isDir.du index d77078b37..676317bf9 100644 --- a/tests/path/isDir.du +++ b/tests/path/isDir.du @@ -3,7 +3,8 @@ * * Testing Path.isDir() * - * Returns true if the given string is a path to a directory, else false. (Linux only) + * Returns true if the given string is a path to a directory, else false. + */ from UnitTest import UnitTest; diff --git a/tests/path/isSymbolicLink.du b/tests/path/isSymbolicLink.du index b2cd06b19..077fafc64 100644 --- a/tests/path/isSymbolicLink.du +++ b/tests/path/isSymbolicLink.du @@ -3,7 +3,7 @@ * * Testing Path.isSymbolicLink() * - * Returns true if the given string is a symbolic Link, else false. (Linux only) + * Returns true if the given string is a symbolic Link, else false. (Linux/Mac only) */ from UnitTest import UnitTest;