diff --git a/ueforth/Makefile b/ueforth/Makefile index 786a6c0..39b5c5d 100644 --- a/ueforth/Makefile +++ b/ueforth/Makefile @@ -77,7 +77,7 @@ WINDOWS_BOOT = common/boot.fs common/terminal.fs windows/windows.fs $(GEN)/windows_boot.h: common/source_to_string.js $(WINDOWS_BOOT) | $(GEN) echo "ok" | cat $(WINDOWS_BOOT) - | $< boot >$@ -ARDUINO_BOOT = common/boot.fs +ARDUINO_BOOT = common/boot.fs arduino/arduino.fs $(GEN)/arduino_boot.h: common/source_to_string.js $(ARDUINO_BOOT) | $(GEN) echo "ok" | cat $(ARDUINO_BOOT) - | $< boot >$@ diff --git a/ueforth/arduino/arduino.fs b/ueforth/arduino/arduino.fs new file mode 100644 index 0000000..b544ffb --- /dev/null +++ b/ueforth/arduino/arduino.fs @@ -0,0 +1,6 @@ +( Map Arduino / ESP32 things to shorter names. ) +: pin ( n n -- ) swap digitalWrite ; +: adc ( n -- n ) analogRead ; +: duty ( n n -- ) 255 ledcAnalogWrite ; +: freq ( n n -- ) 1000 * 13 ledcSetup drop ; +: tone ( n n -- ) 1000 * ledcWriteTone drop ; diff --git a/ueforth/arduino/arduino.template.ino b/ueforth/arduino/arduino.template.ino index adb6f58..fe73791 100644 --- a/ueforth/arduino/arduino.template.ino +++ b/ueforth/arduino/arduino.template.ino @@ -1,5 +1,12 @@ {{opcodes}} +#include +#include +#include +#include +#include +#include + #if defined(ESP32) # define HEAP_SIZE (100 * 1024) # define STACK_SIZE 512 @@ -12,11 +19,61 @@ #endif #define PLATFORM_OPCODE_LIST \ - X("GPIO", OP_GPIO, ) \ + X("pinMode", PIN_MODE, pinMode(*sp, tos); --sp; DROP) \ + X("digitalWrite", DIGITAL_WRITE, digitalWrite(*sp, tos); --sp; DROP) \ + X("analogRead", ANALOG_READ, tos = (cell_t) analogRead(tos)) \ + X("ledcSetup", LEDC_SETUP, \ + tos = (cell_t) (1000000 * ledcSetup(sp[-1], *sp / 1000.0, tos)); sp -= 2) \ + X("ledcAttachPin", ATTACH_PIN, ledcAttachPin(*sp, tos); --sp; DROP) \ + X("ledcDetachPin", DETACH_PIN, ledcDetachPin(tos); DROP) \ + X("ledcRead", LEDC_READ, tos = (cell_t) ledcRead(tos)) \ + X("ledcReadFreq", LEDC_READ_FREQ, tos = (cell_t) (1000000 * ledcReadFreq(tos))) \ + X("ledcWrite", LEDC_WRITE, ledcWrite(*sp, tos); --sp; DROP) \ + X("ledcWriteTone", LEDC_WRITE_TONE, \ + tos = (cell_t) (1000000 * ledcWriteTone(*sp, tos / 1000.0)); --sp) \ + X("ledcWriteNote", LEDC_WRITE_NOTE, \ + tos = (cell_t) (1000000 * ledcWriteNote(sp[-1], (note_t) *sp, tos)); sp -=2) \ + X("MS", MS, mspause(tos); DROP) \ + X("TERMINATE", TERMINATE, exit(tos)) \ + /* File words */ \ + X("R/O", R_O, *++sp = O_RDONLY) \ + X("R/W", R_W, *++sp = O_RDWR) \ + X("W/O", W_O, *++sp = O_WRONLY) \ + X("BIN", BIN, ) \ + X("CLOSE-FILE", CLOSE_FILE, tos = close(tos); tos = tos ? errno : 0) \ + X("OPEN-FILE", OPEN_FILE, cell_t mode = tos; DROP; cell_t len = tos; DROP; \ + memcpy(filename, (void *) tos, len); filename[len] = 0; \ + tos = open(filename, mode, 0777); PUSH tos < 0 ? errno : 0) \ + X("CREATE-FILE", CREATE_FILE, cell_t mode = tos; DROP; cell_t len = tos; DROP; \ + memcpy(filename, (void *) tos, len); filename[len] = 0; \ + tos = open(filename, mode | O_CREAT | O_TRUNC); PUSH tos < 0 ? errno : 0) \ + X("DELETE-FILE", DELETE_FILE, cell_t len = tos; DROP; \ + memcpy(filename, (void *) tos, len); filename[len] = 0; \ + tos = unlink(filename); tos = tos ? errno : 0) \ + X("WRITE-FILE", WRITE_FILE, cell_t fd = tos; DROP; cell_t len = tos; DROP; \ + tos = write(fd, (void *) tos, len); tos = tos != len ? errno : 0) \ + X("READ-FILE", READ_FILE, cell_t fd = tos; DROP; cell_t len = tos; DROP; \ + tos = read(fd, (void *) tos, len); PUSH tos != len ? errno : 0) \ + X("FILE-POSITION", FILE_POSITION, \ + tos = (cell_t) lseek(tos, 0, SEEK_CUR); PUSH tos < 0 ? errno : 0) \ + X("REPOSITION-FILE", REPOSITION_FILE, cell_t fd = tos; DROP; \ + tos = (cell_t) lseek(fd, tos, SEEK_SET); tos = tos < 0 ? errno : 0) \ + X("FILE-SIZE", FILE_SIZE, struct stat st; w = fstat(tos, &st); \ + tos = (cell_t) st.st_size; PUSH w < 0 ? errno : 0) \ + +// TODO: Why doesn't ftruncate exist? +// X("RESIZE-FILE", RESIZE_FILE, cell_t fd = tos; DROP; \ +// tos = ftruncate(fd, tos); tos = tos < 0 ? errno : 0) \ + +static char filename[PATH_MAX]; {{core}} {{boot}} +static void mspause(cell_t ms) { + vTaskDelay(ms / portTICK_PERIOD_MS); +} + void setup() { cell_t *heap = (cell_t *) malloc(HEAP_SIZE); ueforth(0, 0, heap, boot, sizeof(boot)); diff --git a/ueforth/common/core.h b/ueforth/common/core.h index 30f7351..fddc1e6 100644 --- a/ueforth/common/core.h +++ b/ueforth/common/core.h @@ -125,7 +125,7 @@ static void ueforth(int argc, char *argv[], void *heap, register cell_t tos = 0, *ip, w; dcell_t d; udcell_t ud; -#define X(name, op, code) create(name, sizeof(name) - 1, name[0] == ';', && op); +#define X(name, op, code) create(name, sizeof(name) - 1, name[0] == ';', && OP_ ## op); PLATFORM_OPCODE_LIST OPCODE_LIST #undef X @@ -143,7 +143,7 @@ static void ueforth(int argc, char *argv[], void *heap, g_sys.tib = src; g_sys.ntib = src_len; NEXT; -#define X(name, op, code) op: code; NEXT; +#define X(name, op, code) OP_ ## op: { code; } NEXT; PLATFORM_OPCODE_LIST OPCODE_LIST #undef X diff --git a/ueforth/common/opcodes.h b/ueforth/common/opcodes.h index 0ff4d2c..b781192 100644 --- a/ueforth/common/opcodes.h +++ b/ueforth/common/opcodes.h @@ -14,6 +14,7 @@ typedef uint64_t udcell_t; # error "unsupported cell size" #endif +#define PUSH DUP; tos = #define DUP *++sp = tos #define DROP tos = *sp-- #define COMMA(n) *g_sys.heap++ = (n) @@ -27,59 +28,59 @@ typedef uint64_t udcell_t; tos = (cell_t) (d < 0 ? ~(~d / tos) : d / tos) #define OPCODE_LIST \ - X("0=", OP_ZEQUAL, tos = !tos ? -1 : 0) \ - X("0<", OP_ZLESS, tos = (tos|0) < 0 ? -1 : 0) \ - X("+", OP_PLUS, tos = (tos + *sp) | 0; --sp) \ - X("UM/MOD", OP_UMSMOD, UMSMOD) \ - X("*/MOD", OP_SSMOD, SSMOD) \ - X("AND", OP_AND, tos = tos & *sp; --sp) \ - X("OR", OP_OR, tos = tos | *sp; --sp) \ - X("XOR", OP_XOR, tos = tos ^ *sp; --sp) \ - X("DUP", OP_DUP, DUP) \ - X("SWAP", OP_SWAP, w = tos; tos = (*sp)|0; *sp = w) \ - X("OVER", OP_OVER, DUP; tos = sp[-1] | 0) \ - X("DROP", OP_DROP, DROP) \ - X("@", OP_AT, tos = (*(cell_t *) tos)|0) \ - X("L@", OP_LAT, tos = (*(int32_t *) tos)|0) \ - X("C@", OP_CAT, tos = (*(uint8_t *) tos)|0) \ - X("!", OP_STORE, *(cell_t *) tos = (*sp)|0; --sp; DROP) \ - X("L!", OP_LSTORE, *(int32_t *) tos = (*sp)|0; --sp; DROP) \ - X("C!", OP_CSTORE, *(uint8_t *) tos = (*sp)|0; --sp; DROP) \ - X("FILL", OP_FILL, memset((void *) (sp[-1] | 0), tos | 0, (*sp | 0)); sp -= 2; DROP) \ - X("MOVE", OP_MOVE, memmove((void *) (sp[-1] | 0), (void *) (*sp | 0), tos | 0); sp -= 2; DROP) \ - X("SP@", OP_SPAT, DUP; tos = (cell_t) sp) \ - X("SP!", OP_SPSTORE, sp = (cell_t *) tos; DROP) \ - X("RP@", OP_RPAT, DUP; tos = (cell_t) rp) \ - X("RP!", OP_RPSTORE, rp = (cell_t *) tos; DROP) \ - X(">R", OP_TOR, ++rp; *rp = tos; DROP) \ - X("R>", OP_FROMR, DUP; tos = (*rp)|0; --rp) \ - X("R@", OP_RAT, DUP; tos = (*rp)|0) \ - X("EXECUTE", OP_EXECUTE, w = tos; DROP; goto **(void **) w) \ - X("BRANCH", OP_BRANCH, ip = (cell_t *) (*ip | 0)) \ - X("0BRANCH", OP_ZBRANCH, if (!tos) ip = (cell_t *) (*ip | 0); else ++ip; DROP) \ - X("DONEXT", OP_DONEXT, *rp = ((*rp|0) - 1) | 0; \ - if ((*rp|0)) ip = (cell_t *) (*ip | 0); else (--rp, ++ip)) \ - X("DOLIT", OP_DOLIT, DUP; tos = (*ip | 0); ++ip) \ - X("ALITERAL", OP_ALITERAL, COMMA(g_sys.DOLIT_XT | 0); COMMA(tos | 0); DROP) \ - X("CELL", OP_CELL, DUP; tos = sizeof(cell_t)) \ - X("FIND", OP_FIND, tos = find((const char *) (*sp | 0), tos|0)|0; --sp) \ - X("PARSE", OP_PARSE, DUP; tos = parse(tos|0, (cell_t *) ((cell_t) sp | 0))|0) \ - X("S>NUMBER?", OP_CONVERT, \ + X("0=", ZEQUAL, tos = !tos ? -1 : 0) \ + X("0<", ZLESS, tos = (tos|0) < 0 ? -1 : 0) \ + X("+", PLUS, tos = (tos + *sp) | 0; --sp) \ + X("UM/MOD", UMSMOD, UMSMOD) \ + X("*/MOD", SSMOD, SSMOD) \ + X("AND", AND, tos = tos & *sp; --sp) \ + X("OR", OR, tos = tos | *sp; --sp) \ + X("XOR", XOR, tos = tos ^ *sp; --sp) \ + X("DUP", DUP, DUP) \ + X("SWAP", SWAP, w = tos; tos = (*sp)|0; *sp = w) \ + X("OVER", OVER, DUP; tos = sp[-1] | 0) \ + X("DROP", DROP, DROP) \ + X("@", AT, tos = (*(cell_t *) tos)|0) \ + X("L@", LAT, tos = (*(int32_t *) tos)|0) \ + X("C@", CAT, tos = (*(uint8_t *) tos)|0) \ + X("!", STORE, *(cell_t *) tos = (*sp)|0; --sp; DROP) \ + X("L!", LSTORE, *(int32_t *) tos = (*sp)|0; --sp; DROP) \ + X("C!", CSTORE, *(uint8_t *) tos = (*sp)|0; --sp; DROP) \ + X("FILL", FILL, memset((void *) (sp[-1] | 0), tos | 0, (*sp | 0)); sp -= 2; DROP) \ + X("MOVE", MOVE, memmove((void *) (sp[-1] | 0), (void *) (*sp | 0), tos | 0); sp -= 2; DROP) \ + X("SP@", SPAT, DUP; tos = (cell_t) sp) \ + X("SP!", SPSTORE, sp = (cell_t *) tos; DROP) \ + X("RP@", RPAT, DUP; tos = (cell_t) rp) \ + X("RP!", RPSTORE, rp = (cell_t *) tos; DROP) \ + X(">R", TOR, ++rp; *rp = tos; DROP) \ + X("R>", FROMR, DUP; tos = (*rp)|0; --rp) \ + X("R@", RAT, DUP; tos = (*rp)|0) \ + X("EXECUTE", EXECUTE, w = tos; DROP; goto **(void **) w) \ + X("BRANCH", BRANCH, ip = (cell_t *) (*ip | 0)) \ + X("0BRANCH", ZBRANCH, if (!tos) ip = (cell_t *) (*ip | 0); else ++ip; DROP) \ + X("DONEXT", DONEXT, *rp = ((*rp|0) - 1) | 0; \ + if ((*rp|0)) ip = (cell_t *) (*ip | 0); else (--rp, ++ip)) \ + X("DOLIT", DOLIT, DUP; tos = (*ip | 0); ++ip) \ + X("ALITERAL", ALITERAL, COMMA(g_sys.DOLIT_XT | 0); COMMA(tos | 0); DROP) \ + X("CELL", CELL, DUP; tos = sizeof(cell_t)) \ + X("FIND", FIND, tos = find((const char *) (*sp | 0), tos|0)|0; --sp) \ + X("PARSE", PARSE, DUP; tos = parse(tos|0, (cell_t *) ((cell_t) sp | 0))|0) \ + X("S>NUMBER?", CONVERT, \ tos = convert((const char *) (*sp | 0), tos|0, (cell_t *) ((cell_t) sp | 0))|0; \ if (!tos) --sp) \ - X("CREATE", OP_CREATE, DUP; DUP; tos = parse(32, (cell_t *) ((cell_t) sp | 0))|0; \ - create((const char *) (*sp | 0), tos|0, 0, && OP_DOCREATE); \ + X("CREATE", CREATE, DUP; DUP; tos = parse(32, (cell_t *) ((cell_t) sp | 0))|0; \ + create((const char *) (*sp | 0), tos|0, 0, && OP_DOCREATE); \ COMMA(0); --sp; DROP) \ - X("DOES>", OP_DOES, DOES((cell_t *) ((cell_t) ip|0)); ip = (cell_t *) (*rp | 0); --rp) \ - X("IMMEDIATE", OP_IMMEDIATE, IMMEDIATE()) \ - X("'SYS", OP_SYS, DUP; tos = (cell_t) &g_sys) \ - X(":", OP_COLON, DUP; DUP; tos = parse(32, (cell_t *) ((cell_t) sp | 0))|0; \ - create((const char *) (*sp | 0), tos|0, 0, && OP_DOCOLON); \ + X("DOES>", DOES, DOES((cell_t *) ((cell_t) ip|0)); ip = (cell_t *) (*rp | 0); --rp) \ + X("IMMEDIATE", IMMEDIATE, IMMEDIATE()) \ + X("'SYS", SYS, DUP; tos = (cell_t) &g_sys) \ + X(":", COLON, DUP; DUP; tos = parse(32, (cell_t *) ((cell_t) sp | 0))|0; \ + create((const char *) (*sp | 0), tos|0, 0, && OP_DOCOLON); \ g_sys.state = -1; --sp; DROP) \ - X("EVALUATE1", OP_EVALUATE1, \ + X("EVALUATE1", EVALUATE1, \ DUP; sp = (cell_t *) ((cell_t) evaluate1((cell_t *) ((cell_t) sp | 0))|0); \ w = (*sp | 0); --sp; DROP; \ if (w) goto **(void **) w) \ - X("EXIT", OP_EXIT, ip = (cell_t *) (*rp | 0); --rp) \ - X(";", OP_SEMICOLON, COMMA(g_sys.DOEXIT_XT | 0); g_sys.state = 0) \ + X("EXIT", EXIT, ip = (cell_t *) (*rp | 0); --rp) \ + X(";", SEMICOLON, COMMA(g_sys.DOEXIT_XT | 0); g_sys.state = 0) \ diff --git a/ueforth/posix/posix_main.c b/ueforth/posix/posix_main.c index c4bb3d2..d60217e 100644 --- a/ueforth/posix/posix_main.c +++ b/ueforth/posix/posix_main.c @@ -8,7 +8,7 @@ #define STACK_SIZE (16 * 1024) #define PLATFORM_OPCODE_LIST \ - X("DLSYM", OP_DLSYM, tos = (cell_t) dlsym((void *) *sp, (void *) tos); --sp) \ + X("DLSYM", DLSYM, tos = (cell_t) dlsym((void *) *sp, (void *) tos); --sp) \ CALLING_OPCODE_LIST \ #include "common/core.h" diff --git a/ueforth/web/dump_web_opcodes.c b/ueforth/web/dump_web_opcodes.c index 32937a8..ecfe6fd 100644 --- a/ueforth/web/dump_web_opcodes.c +++ b/ueforth/web/dump_web_opcodes.c @@ -4,13 +4,13 @@ #include "common/opcodes.h" #define PLATFORM_OPCODE_LIST \ - X("CALL", OP_CALL, sp = Call(sp|0, tos|0) | 0; DROP) \ + X("CALL", CALL, sp = Call(sp|0, tos|0) | 0; DROP) \ enum { OP_DOCOLON = 0, OP_DOCREATE = 1, OP_DODOES = 2, -#define X(name, op, code) op, +#define X(name, op, code) OP_ ## op, PLATFORM_OPCODE_LIST OPCODE_LIST #undef X @@ -18,12 +18,12 @@ enum { int main(int argc, char *argv[]) { if (argc == 2 && strcmp(argv[1], "cases") == 0) { -#define X(name, op, code) printf(" case %d: %s; break;\n", op, #code); +#define X(name, op, code) printf(" case %d: %s; break;\n", OP_ ## op, #code); PLATFORM_OPCODE_LIST OPCODE_LIST #undef X } else if (argc == 2 && strcmp(argv[1], "dict") == 0) { -#define X(name, op, code) printf(" create(" #name ", %d);\n", op); +#define X(name, op, code) printf(" create(" #name ", %d);\n", OP_ ## op); PLATFORM_OPCODE_LIST OPCODE_LIST #undef X diff --git a/ueforth/windows/windows_main.c b/ueforth/windows/windows_main.c index 9f36846..1db572f 100644 --- a/ueforth/windows/windows_main.c +++ b/ueforth/windows/windows_main.c @@ -9,9 +9,9 @@ #define STACK_SIZE (16 * 1024) #define PLATFORM_OPCODE_LIST \ - X("GETPROCADDRESS", OP_GETPROCADDRESS, \ + X("GETPROCADDRESS", GETPROCADDRESS, \ tos = (cell_t) GetProcAddress((HMODULE) *sp, (LPCSTR) tos); --sp) \ - X("LOADLIBRARYA", OP_LOADLIBRARYA, \ + X("LOADLIBRARYA", LOADLIBRARYA, \ tos = (cell_t) LoadLibraryA((LPCSTR) tos)) \ CALLING_OPCODE_LIST \