From c78d1744868cce048377896a8333813d43d322a9 Mon Sep 17 00:00:00 2001 From: Ivan Krasilnikov Date: Thu, 12 Feb 2026 13:25:31 +0800 Subject: [PATCH] Makefile and fixes for modern Linux Minimal fixes needed to get dscriptcpp to build and run on modern systems. Added a self-contained Makefile, REPL script for testing and build instructions. --- Makefile | 72 +++++++++++++++++++++++++++++++++++++++++++ README.md | 16 ++++++++++ repl.js | 24 +++++++++++++++ src/dmgc/gc.c | 4 +-- src/dscript/dglobal.c | 2 ++ src/dscript/dobject.c | 2 ++ src/dscript/lexer.h | 2 +- src/dscript/value.h | 7 ++--- src/root/lstring.h | 2 +- src/root/root.c | 4 +-- 10 files changed, 124 insertions(+), 11 deletions(-) create mode 100644 Makefile create mode 100644 repl.js diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..4db482c --- /dev/null +++ b/Makefile @@ -0,0 +1,72 @@ +# Minimal build script for modern Linux systems. Needs i386 multilib gcc. + +CC = g++ --std=gnu++98 -fpermissive -w -m32 -static -Isrc/dmgc -Isrc/root -DUNICODE -DVPTR_INDEX=0 -Dlinux -O + +DSCRIPT_SRCS = \ + src/dmgc/bits.c \ + src/dmgc/gc.c \ + src/dmgc/linux.c \ + src/dscript/darguments.c \ + src/dscript/darray.c \ + src/dscript/dboolean.c \ + src/dscript/ddate.c \ + src/dscript/derror.c \ + src/dscript/dfunction.c \ + src/dscript/dglobal.c \ + src/dscript/dmath.c \ + src/dscript/dnative.c \ + src/dscript/dnumber.c \ + src/dscript/dobject.c \ + src/dscript/dregexp.c \ + src/dscript/dscript.c \ + src/dscript/dstring.c \ + src/dscript/dstring2.c \ + src/dscript/evalerror.c \ + src/dscript/expression.c \ + src/dscript/function.c \ + src/dscript/id.c \ + src/dscript/identifier.c \ + src/dscript/ir.c \ + src/dscript/iterator.c \ + src/dscript/lexer.c \ + src/dscript/opcodes.c \ + src/dscript/optimize.c \ + src/dscript/parse.c \ + src/dscript/program.c \ + src/dscript/property.c \ + src/dscript/rangeerror.c \ + src/dscript/referenceerror.c \ + src/dscript/response.c \ + src/dscript/scope.c \ + src/dscript/statement.c \ + src/dscript/symbol.c \ + src/dscript/syntaxerror.c \ + src/dscript/text.c \ + src/dscript/threadcontext.c \ + src/dscript/toir.c \ + src/dscript/typeerror.c \ + src/dscript/urierror.c \ + src/dscript/value.c \ + src/root/date.c \ + src/root/dateparse.c \ + src/root/dchar.c \ + src/root/dmgcmem.c \ + src/root/lstring.c \ + src/root/mutex.c \ + src/root/port.c \ + src/root/printf.c \ + src/root/random.c \ + src/root/regexp.c \ + src/root/root.c \ + src/root/stringcommon.c \ + src/root/stringtable.c \ + src/root/thread.c + +dscript: + $(CC) -o dscript $(DSCRIPT_SRCS) + +testgc: + $(CC) -o testgc src/dmgc/testgc.c src/dmgc/gc.c src/dmgc/bits.c src/dmgc/linux.c src/root/printf.c + +clean: + rm -f dscript testgc diff --git a/README.md b/README.md index adcb97b..6684df8 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,18 @@ # DscriptCPP Javascript implementation in C++ + +## Building on modern Linux +This is an ancient project developed during x86 era. Due to some assumptions in the code about running on a 32-bit processor, it won't work well with modern 64-bit compilers - you need i386 multilib gcc to build it. Here's an example how to build it in a docker container: + +``` +$ podman run -it --arch amd64 -v $PWD:$PWD -w $PWD debian:stable bash +$ dpkg --add-architecture i386 && apt-get update -y && apt-get install -y build-essential g++-multilib +$ make +$ ./dscript repl.js +Digital Mars DMDScript 1.05 +http://www.digitalmars.com +Compiled by GNU C++ +written by Walter Bright +1 source files +> +``` diff --git a/repl.js b/repl.js new file mode 100644 index 0000000..78cc5c7 --- /dev/null +++ b/repl.js @@ -0,0 +1,24 @@ +// Basic REPL script using eval() and dscript's built-ins + +var console = {log: println}; +var __lastLine; + +for (;;) { + print('> '); // dscript's print() doesn't append newline + + var __line = readln(); + if (__line == null || (__line == '' && __lastLine == '')) { // probably EOF + break; + } + + __lastLine = __line; + + try { + var __res = eval(__line); + if (typeof __res != "undefined") { + console.log("" + __res); + } + } catch (__err) { + console.log("" + __err); + } +} diff --git a/src/dmgc/gc.c b/src/dmgc/gc.c index c3cb13e..fd14c50 100644 --- a/src/dmgc/gc.c +++ b/src/dmgc/gc.c @@ -1877,9 +1877,9 @@ Pool::Pool(unsigned npages) #endif WPRINTF(L"GC fail: poolsize = x%x, errno = %d\n", poolsize, errno); #if USEROOT - PRINTF("message = '%s'\n", sys_errlist[errno]); + PRINTF("message = '%s'\n", strerror(errno)); #else - printf("message = '%s'\n", sys_errlist[errno]); + printf("message = '%s'\n", strerror(errno)); #endif npages = 0; poolsize = 0; diff --git a/src/dscript/dglobal.c b/src/dscript/dglobal.c index f0975aa..b0f2c9a 100644 --- a/src/dscript/dglobal.c +++ b/src/dscript/dglobal.c @@ -1042,6 +1042,7 @@ BUILTIN_FUNCTION2(Dglobal_, readln, 0) BUILTIN_FUNCTION2(Dglobal_, getenv, 1) { +#if !defined(linux) // Our own extension Value::copy(ret, &vundefined); if (argc) @@ -1056,6 +1057,7 @@ BUILTIN_FUNCTION2(Dglobal_, getenv, 1) else Value::copy(ret, &vnull); } +#endif return NULL; } diff --git a/src/dscript/dobject.c b/src/dscript/dobject.c index a0be186..b586bcd 100644 --- a/src/dscript/dobject.c +++ b/src/dscript/dobject.c @@ -15,7 +15,9 @@ * Use at your own risk. There is no warranty, express or implied. */ +#if !defined(linux) #include +#endif #include #include diff --git a/src/dscript/lexer.h b/src/dscript/lexer.h index 0385a13..ab0eff5 100644 --- a/src/dscript/lexer.h +++ b/src/dscript/lexer.h @@ -165,7 +165,7 @@ struct Lexer : Mem ~Lexer(); static TOK isKeyword(dchar *s, unsigned len); - void initKeywords(); + static void initKeywords(); TOK nextToken(); void insertSemicolon(dchar *loc); void rescan(); diff --git a/src/dscript/value.h b/src/dscript/value.h index 26e5fb2..f533418 100644 --- a/src/dscript/value.h +++ b/src/dscript/value.h @@ -57,6 +57,7 @@ struct CallContext; // VPTR_INDEX is the ith pointer where the vptr is stored in the Value object +#if !defined(VPTR_INDEX) #ifdef __GNUC__ #define VPTR_INDEX 3 #endif @@ -68,7 +69,7 @@ struct CallContext; #ifdef __DMC__ #define VPTR_INDEX 0 #endif - +#endif struct Value { @@ -122,10 +123,6 @@ struct Value ((long *)to)[0] = ((long *)from)[0]; ((long *)to)[2] = ((long *)from)[2]; ((long *)to)[3] = ((long *)from)[3]; -#elif defined __GNUC__ - ((long long *)to)[0] = ((long long *)from)[0]; - ((long *)to)[3] = ((long *)from)[3]; - // Don't copy padforgcc #else memcpy(to, from, sizeof(Value)); #endif diff --git a/src/root/lstring.h b/src/root/lstring.h index 0492228..1693849 100644 --- a/src/root/lstring.h +++ b/src/root/lstring.h @@ -31,7 +31,7 @@ struct Lstring unsigned length; #if defined __GNUC__ - dchar string[1]; + dchar string[]; #else // Disable warning about nonstandard extension #pragma warning (disable : 4200) diff --git a/src/root/root.c b/src/root/root.c index d7d44e7..2737b2f 100644 --- a/src/root/root.c +++ b/src/root/root.c @@ -942,7 +942,7 @@ int File::read() #if defined(linux) ssize_t numread; // must be initialized before any "goto" off_t size; - struct stat buf; + struct stat64 buf; int result = 0; char *name = this->name->toChars(); @@ -961,7 +961,7 @@ int File::read() ref = 0; // we own the buffer now //PRINTF("\tfile opened\n"); - if (fstat(fd, &buf)) + if (fstat64(fd, &buf)) { error(DTEXT("\tfstat error, errno = %d\n"),errno); goto err2;