diff --git a/.github/workflows/build-standalone.yml b/.github/workflows/build-standalone.yml index 2111b1b..32758e9 100644 --- a/.github/workflows/build-standalone.yml +++ b/.github/workflows/build-standalone.yml @@ -15,9 +15,5 @@ jobs: steps: - uses: actions/checkout@v2 - uses: ./.github/actions/setup - - run: make -C src/standalone install-deps all - # TODO: Windows support - if: runner.os != 'Windows' + - run: make -C src/standalone install-deps package - run: make -C src/standalone check - # TODO: Windows support - if: runner.os != 'Windows' \ No newline at end of file diff --git a/.github/workflows/publish-standalone.yml b/.github/workflows/publish-standalone.yml index 8fae413..a0dbde1 100644 --- a/.github/workflows/publish-standalone.yml +++ b/.github/workflows/publish-standalone.yml @@ -12,7 +12,7 @@ jobs: needs: build strategy: matrix: - os: [macos-latest, ubuntu-18.04] + os: [macos-latest, ubuntu-18.04, windows-latest] runs-on: ${{ matrix.os }} steps: - uses: actions/checkout@v2 diff --git a/README.md b/README.md index 67de77a..c99149d 100644 --- a/README.md +++ b/README.md @@ -39,9 +39,9 @@ document](doc/Design.md).
WAForth console
-
+
-Thurtle program +Thurtle program
WAForth integrated in Thurtle, a turtle graphics programming environment using Forth
@@ -59,6 +59,12 @@ WebAssembly engine that supports the [WebAssembly C API](https://github.com/WebAssembly/wasm-c-api) (although some engines have [known issues](https://github.com/remko/waforth/issues/6#issue-326830993)). +
+
+Thurtle program +
+
Standalone WAForth shell executable
+
## Using WAForth in a JavaScript application diff --git a/doc/standalone.png b/doc/standalone.png new file mode 100644 index 0000000..63698da Binary files /dev/null and b/doc/standalone.png differ diff --git a/src/standalone/.gitignore b/src/standalone/.gitignore index 7cf6216..290c0e5 100644 --- a/src/standalone/.gitignore +++ b/src/standalone/.gitignore @@ -2,4 +2,4 @@ /waforth_core.h /wasm-micro-runtime /wasmtime-* -/*.tgz \ No newline at end of file +/*.tgz diff --git a/src/standalone/Makefile b/src/standalone/Makefile index ee91525..55a4a6a 100644 --- a/src/standalone/Makefile +++ b/src/standalone/Makefile @@ -1,15 +1,7 @@ -UNAME_S=$(shell uname -s) -UNAME_P=$(shell uname -p) - -ifeq (, $(shell which gtar)) -TAR := tar -else -# bsd-tar corrupts files on GitHub: https://github.com/actions/virtual-environments/issues/2619 -TAR := gtar -endif - .DEFAULT_GOAL := all +VERSION?=$(shell cat ../../package.json | grep '"version"' | sed -e 's/.*:.*"\(.*\)".*/\1/') + ################################################ # WebAssembly engine configuration ################################################ @@ -23,37 +15,68 @@ LIBS:=$(WASMER_DIR)/lib/libwasmer.a else # Wasmtime (https://wasmtime.dev) -ifeq ($(UNAME_S),Darwin) -WASMTIME_DIR=wasmtime-v0.37.0-x86_64-macos-c-api -WASMTIME_RELEASE_URL=https://github.com/bytecodealliance/wasmtime/releases/download/v0.37.0/wasmtime-v0.37.0-x86_64-macos-c-api.tar.xz +ifeq ($(OS),Windows_NT) + +WASMTIME_DIR=wasmtime-v1.0.0-x86_64-mingw-c-api +WASMTIME_RELEASE_URL=https://github.com/bytecodealliance/wasmtime/releases/download/v1.0.0/wasmtime-v1.0.0-x86_64-mingw-c-api.zip +CC=gcc +CFLAGS=-DWASM_API_EXTERN= +LIBS=-luserenv -lole32 -lntdll -lws2_32 -lkernel32 -lbcrypt +RESOURCE_OBJECTS=waforth.res + +install-deps: + -rm -rf wasmtime-* + curl -o $(WASMTIME_DIR).zip -L -s $(WASMTIME_RELEASE_URL) + unzip $(WASMTIME_DIR).zip + +package: waforth + 7z a -tzip waforth-v$(VERSION)-windows.zip waforth.exe + +comma:=, +%.res: %.rc + windres --use-temp-file $< -DVERSION_STRING='"$(VERSION)"' -DVERSION_TUPLE='$(subst .,$(comma),$(VERSION)),0' -O coff -o $@ + else -WASMTIME_DIR=wasmtime-v0.37.0-x86_64-linux-c-api -WASMTIME_RELEASE_URL=https://github.com/bytecodealliance/wasmtime/releases/download/v0.37.0/wasmtime-v0.37.0-x86_64-linux-c-api.tar.xz -LIBS=-lpthread -lm -ldl + +ifeq (, $(shell which gtar)) +TAR := tar +else +# bsd-tar corrupts files on GitHub: https://github.com/actions/virtual-environments/issues/2619 +TAR := gtar +endif +UNAME_S=$(shell uname -s) +UNAME_P=$(shell uname -p) +ifeq ($(UNAME_S),Darwin) +WASMTIME_DIR=wasmtime-v1.0.1-x86_64-macos-c-api +WASMTIME_RELEASE_URL=https://github.com/bytecodealliance/wasmtime/releases/download/v1.0.1/wasmtime-v1.0.1-x86_64-macos-c-api.tar.xz +PACKAGE_SUFFIX=x86_64-macos +else +WASMTIME_DIR=wasmtime-v1.0.1-x86_64-linux-c-api +WASMTIME_RELEASE_URL=https://github.com/bytecodealliance/wasmtime/releases/download/v1.0.1/wasmtime-v1.0.1-x86_64-linux-c-api.tar.xz +LIBS=-lpthread -lm -ldl +PACKAGE_SUFFIX=x86_64-linux endif -CFLAGS=-I$(WASMTIME_DIR)/include -LIBS:=$(WASMTIME_DIR)/lib/libwasmtime.a $(LIBS) install-deps: -rm -rf wasmtime-* curl -L -s $(WASMTIME_RELEASE_URL) | tar xJv + +package: waforth + $(TAR) czf waforth-v$(VERSION)-$(PACKAGE_SUFFIX).tgz waforth + endif +endif +CFLAGS:=-I$(WASMTIME_DIR)/include $(CFLAGS) +LIBS:=$(WASMTIME_DIR)/lib/libwasmtime.a $(LIBS) ################################################ -ifeq ($(UNAME_S),Darwin) -PACKAGE_SUFFIX=x86_64-macos -else -PACKAGE_SUFFIX=x86_64-linux -endif - -VERSION?=$(shell cat ../../package.json | grep '"version"' | sed -e 's/.*:.*"\(.*\)".*/\1/') BIN2H=../../scripts/bin2h WAT2WASM=wat2wasm WAT2WASM_FLAGS=--debug-names CFLAGS:=-DVERSION='"$(VERSION)"' $(CFLAGS) -OBJECTS=main.o +OBJECTS=main.o $(RESOURCE_OBJECTS) all: waforth @@ -62,17 +85,16 @@ waforth: $(OBJECTS) main.o: waforth_core.h +icon.ico: ../../doc/logo.svg + convert -background transparent $< -define icon:auto-resize=16,32,48,64,256 $@ + waforth_core.wasm: ../waforth.wat $(WAT2WASM) $(WAT2WASM_FLAGS) -o $@ $< waforth_core.h: waforth_core.wasm $(BIN2H) $< $@ -.PHONY: install-deps - -.PHONY: package -package: waforth - $(TAR) czf waforth-v$(VERSION)-$(PACKAGE_SUFFIX).tgz waforth +.PHONY: install-deps package .PHONY: check check: diff --git a/src/standalone/README.md b/src/standalone/README.md index 55e4b5e..97903c9 100644 --- a/src/standalone/README.md +++ b/src/standalone/README.md @@ -1,4 +1,4 @@ -# Standalone native WAForth binary +# Standalone native WAForth executable This directory contains a small C program to run the WAForth WebAssembly core in a native WebAssembly engine. @@ -9,6 +9,13 @@ WebAssembly engine that supports the [WebAssembly C API](https://github.com/WebAssembly/wasm-c-api) (although some engines have [known issues](https://github.com/remko/waforth/issues/6#issue-326830993)). +
+
+Thurtle program +
+
Standalone WAForth shell executable
+
+ ## Download You can download a pre-built binary of the standalone shell from diff --git a/src/standalone/icon.ico b/src/standalone/icon.ico new file mode 100644 index 0000000..b9466d8 Binary files /dev/null and b/src/standalone/icon.ico differ diff --git a/src/standalone/main.c b/src/standalone/main.c index ab24b01..a163f5f 100644 --- a/src/standalone/main.c +++ b/src/standalone/main.c @@ -1,8 +1,12 @@ -#include +#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__) +#include +#else #include +#endif #include "waforth_core.h" #include "wasm.h" +#include #ifndef VERSION #define VERSION "dev" @@ -63,6 +67,19 @@ wasm_trap_t *read_cb(const wasm_val_vec_t *args, wasm_val_vec_t *results) { } wasm_trap_t *key_cb(const wasm_val_vec_t *args, wasm_val_vec_t *results) { +#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__) + HANDLE h = GetStdHandle(STD_INPUT_HANDLE); + if (h == NULL) { + return trap_from_string("no console"); + } + DWORD mode; + GetConsoleMode(h, &mode); + SetConsoleMode(h, mode & ~(ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT)); + TCHAR ch = 0; + DWORD cc; + ReadConsole(h, &ch, 1, &cc, NULL); + SetConsoleMode(h, mode); +#else struct termios old, current; tcgetattr(0, &old); current = old; @@ -71,6 +88,7 @@ wasm_trap_t *key_cb(const wasm_val_vec_t *args, wasm_val_vec_t *results) { tcsetattr(0, TCSANOW, ¤t); char ch = getchar(); tcsetattr(0, TCSANOW, &old); +#endif results->data[0].kind = WASM_I32; results->data[0].of.i32 = ch; return NULL; diff --git a/src/standalone/waforth.rc b/src/standalone/waforth.rc new file mode 100644 index 0000000..ecb3feb --- /dev/null +++ b/src/standalone/waforth.rc @@ -0,0 +1,28 @@ +#pragma code_page(65001) + +id ICON "icon.ico" + +// See https://learn.microsoft.com/en-us/windows/win32/menurc/versioninfo-resource +1 VERSIONINFO +FILEVERSION VERSION_TUPLE +PRODUCTVERSION VERSION_TUPLE +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "0409FDE9" + BEGIN + VALUE "CompanyName", "Remko Tronçon" + VALUE "FileDescription", "WAForth" + VALUE "FileVersion", VERSION_STRING + VALUE "InternalName", "waforth" + VALUE "LegalCopyright", "© 2022 Remko Tronçon" + VALUE "OriginalFilename", "waforth.exe" + VALUE "ProductName", "WAForth" + VALUE "ProductVersion", VERSION_STRING + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 65001 + END +END