Compare commits

...

278 Commits

Author SHA1 Message Date
c825146c28 Remove some esp32 platform things (that came from where?) 2025-05-02 13:07:04 -10:00
6ddf643787 Add SPIFFS.exists 2025-05-02 12:40:43 -10:00
399234677d Add Serial/Serial2 begin3 and writeChar 2025-05-02 12:39:47 -10:00
d1bcb86c68 Update documentation 2025-05-01 15:32:56 -10:00
a88bbfda12 Convert Arduino bool values to forth flags 2025-05-01 15:32:56 -10:00
e7c041eeb2 Add more MDNS functions 2025-05-01 15:32:56 -10:00
ac6abf445b Improve terminal, update mobile web tag. 2025-04-22 23:32:02 -07:00
2126dab2c0 Wine changed behavior switching. 2025-03-25 11:52:05 -07:00
53dfc659c3 Adding infix and parsing example. 2025-01-25 09:31:27 -08:00
0fc77179af Move comment to allow start script to override (. 2025-01-12 11:15:36 -08:00
cb5da2542a Use a console window for windows tests. 2024-12-01 21:30:35 -08:00
8ec7e2c5c4 Fixed some windows types.
Amazing this didn't fail before.
Likely the "magic" of padding.
2024-12-01 21:26:27 -08:00
0823c179fa Added field accessors. 2024-11-30 23:21:34 -08:00
9ae74fa183 Refactor structures more. 2024-11-29 16:21:00 -08:00
2ca333a0fa Various structure related cleanups. 2024-11-29 16:07:00 -08:00
4425ffadea Give windows handles a name. 2024-11-29 14:49:28 -08:00
db30147131 Fixed several structure errors in windows, and one in x11. 2024-11-28 17:50:36 -08:00
360417dd53 Fix windows struct size bug. 2024-11-16 19:07:30 -08:00
58205f2738 Fix 2024-11-15 20:36:22 -08:00
e417373461 Fix null etc. 2024-11-15 20:23:16 -08:00
0c9ba3ef86 Tweaks 2024-11-15 20:03:00 -08:00
eeb10b4bcd Adding more. 2024-11-15 18:45:26 -08:00
5cc284e6b0 Tweaks 2024-11-15 17:42:40 -08:00
47c9ec02ba Fix 2024-11-15 13:52:01 -08:00
0bf95dc6c3 Fix more things. 2024-11-14 23:05:24 -08:00
4ed9475c81 Revise example. 2024-11-14 21:05:55 -08:00
8c010e1b24 Tweak example. 2024-11-14 20:56:28 -08:00
e79a432876 Update headers, fix more. 2024-11-14 20:21:39 -08:00
edab2d382f Adding WIP w/ gemini example. 2024-11-14 08:13:28 -08:00
3010f6c2b4 Move 0, -1, 1 to internals vocabulary. 2024-11-09 11:06:50 -08:00
b3ca67eaf6 Tweak 2024-11-08 20:17:08 -08:00
abd9118fb3 Tweak 2024-11-08 19:14:00 -08:00
af641b0578 Added into example. 2024-11-08 19:12:02 -08:00
51c224affd Add complex number example. 2024-11-08 17:54:49 -08:00
ffd0226fdb Fix bug with 10 and 41. 2024-11-07 19:00:33 -08:00
1316a3144e Adding verbosity option. 2024-11-03 13:27:31 -08:00
dfc18bc8c8 Fix bug. 2024-10-26 12:21:40 -07:00
5a2162cbf6 Bump version. 2024-10-26 12:15:00 -07:00
b11d4f18d5 Fix typo. 2024-10-26 12:14:28 -07:00
eeaad939a2 Adding HTTPClient, fix esp32 build board, deprecate old spi flash. 2024-10-26 09:59:55 -07:00
c5ac9b0df0 Adding quick web serial terminal. 2024-08-23 15:15:41 -07:00
d9de300c08 Drop dup. 2024-08-11 00:36:05 -07:00
fe6acd0bb6 Adding SD_MMC.setPins 2024-08-11 00:01:49 -07:00
dd166397c9 Improve terminal. 2024-08-10 12:05:48 -07:00
622a048d92 Add control codes to web keyboard. 2024-08-10 10:38:22 -07:00
8ab745ab9c Adding web serial. 2024-08-05 10:24:03 -07:00
de39be5392 Add arduino-esp32 3.x compatibility. 2024-07-21 17:41:19 -07:00
c4f0895e54 Make boxes scale in a more stable way. 2024-05-16 21:18:49 -07:00
4284a22b28 Only focus on win64. 2024-05-09 18:57:02 -07:00
0f9cac2ab4 Fixing web numeric conversion.
When convert got "converted" to web,
and unsigned type didn't use the >>> operator.
This leads to errors in excluding characters like commas.
2024-05-08 20:27:27 -07:00
3a125e4635 Bump version, drop linux bins + win32. 2024-05-05 10:07:29 -07:00
6c195ce1f4 Tweak build. 2024-05-05 09:47:38 -07:00
d4a87d3b00 Move to svelter icon.
It seems weird to have a 74K icon for a Forth.
Moving to a lower res one in same vein without the rescaling.
2024-05-05 09:42:41 -07:00
3f6c7d1dbe Reduce evaluate1. 2024-04-20 22:20:26 -07:00
f08769855d Make notfound work right with word name. 2024-04-20 16:08:37 -07:00
9477781530 Adding logs example. 2024-04-20 15:59:20 -07:00
08634823da Fix execute bit on some examples. 2024-04-20 12:24:28 -07:00
74d744dd00 Adding Recognizers, and more.
Adding the proposed recognizers vocabulary, including a limited test.
Fixing windows build to better handle different VS versions.
Fixing various hidden word bugs.
Adding 3DUP opcode.
Bumping version number.
2024-04-20 02:10:42 -07:00
5619997682 Fix create-file to truncate file. 2024-03-03 00:49:24 -08:00
65eb318f2c Make Ctrl-P work in addition to Ctrl-S in visual editor. 2024-02-24 12:34:12 -08:00
854b3b5d74 Fixed SPACES issue, also fixed redirection error bug in build. 2024-02-24 12:30:08 -08:00
eaa8a3c4c3 Made posix terminal IO avoid spin looping.
Using raw mode + delay in the right places to
allow tasks to work while also supporting key?
2024-02-24 12:10:47 -08:00
9468c53ab9 Making build work without ImageMagick. 2024-02-24 10:51:02 -08:00
f9d1b6102f Fixing build to tolerate some missing dependencies.
Be able to build without nodejs and d8.
2024-02-24 10:03:09 -08:00
aa69b68412 Droping make build in favor of ninja.
Bumping version.
Adding esp32 flashing + vetting.
2024-01-15 14:04:46 -08:00
bdc5b4e337 Add install of optional modules. 2024-01-15 12:06:34 -08:00
29bd06fed8 Externalized version numbers. 2024-01-15 11:52:11 -08:00
8aff943a00 Convert more tests to new build. 2024-01-15 11:37:13 -08:00
b5aec80fd2 Adding esp32-sim test. 2024-01-14 21:27:36 -08:00
b6c5fd7071 Add fast mode. 2024-01-14 21:13:26 -08:00
6b4f49e8e4 Disable color on windows tests until we can detect the tty. 2024-01-14 19:49:39 -08:00
0373e9c619 Adding more shortcuts from Makefile. 2024-01-14 19:32:21 -08:00
59a78336bb Fix windows build issue. 2024-01-02 21:39:34 -08:00
21cf660212 Made build work partially outside windows. 2024-01-02 21:24:51 -08:00
c9742cebf8 Fix up output. 2024-01-01 23:20:23 -08:00
2980458eff Refine version + publish. 2024-01-01 23:19:33 -08:00
5d0f2ad3b9 Fix deploy. 2024-01-01 23:07:29 -08:00
af26e61de9 Fix up site. 2024-01-01 22:18:32 -08:00
5d6e344357 Revise publish. 2024-01-01 22:16:38 -08:00
f70f802a75 Fix publish more. 2024-01-01 22:15:15 -08:00
a6c6b8d25f Adding publish, untested. 2024-01-01 22:04:40 -08:00
3a17582a8c More working in ninja. 2024-01-01 20:16:37 -08:00
7209ca594a Adding flashing. 2024-01-01 19:58:23 -08:00
1e01a47380 Closer. 2024-01-01 18:39:27 -08:00
67898d2a03 Improve revision handling. 2024-01-01 17:58:20 -08:00
b222a19994 Make root more flexible. 2024-01-01 17:09:16 -08:00
a8fb9ae008 Make output more verbose. 2024-01-01 16:54:35 -08:00
b5ee992a86 Refine. 2024-01-01 16:47:01 -08:00
8987068dac Restructure. 2024-01-01 16:34:02 -08:00
a69961d90d Reroot. 2024-01-01 15:50:27 -08:00
b8f4a7b3c4 Refine. 2023-12-31 23:00:11 -08:00
311a2d88f0 Some test running. 2023-12-31 22:37:08 -08:00
14ede079b7 Tweak 2023-12-31 22:07:03 -08:00
b331d712d0 Tweak. 2023-12-31 21:47:42 -08:00
db939fb889 Added install step. 2023-12-31 21:40:52 -08:00
0e8264fa09 Adding clean target. 2023-12-31 21:33:01 -08:00
a7fbed4c8c Fix up web. 2023-12-31 16:35:59 -08:00
9283b804e1 Add site things to ninja build. 2023-12-31 16:09:04 -08:00
8160a3cb1d Added zip files. 2023-12-24 17:35:14 -08:00
18c38cab15 Put back aliases. 2023-12-24 14:06:30 -08:00
92ace2753e Use implicit mkdir. 2023-12-24 14:03:53 -08:00
bf21b0f3c2 Tweak 2023-12-24 13:38:22 -08:00
8f0aaba643 Fixup ninja build more. 2023-12-23 18:14:32 -08:00
7455e6b511 Windows builds with ninja. 2023-12-23 17:44:45 -08:00
de7da20fe4 Improve for win. 2023-12-23 16:01:37 -08:00
be8b36a372 Fix. 2023-12-23 10:04:39 -08:00
4ee3646b73 More. 2023-12-23 10:03:41 -08:00
dc80ca74c5 Factor. 2023-12-23 09:47:36 -08:00
5d1dbd3001 Builds posix with ninja. 2023-12-23 00:16:21 -08:00
a28f59cfe7 Fix 2023-12-22 23:58:17 -08:00
0ee959ed3b Refine. 2023-12-22 23:28:50 -08:00
f93676eded Tweak 2023-12-22 22:45:56 -08:00
e8589496a9 Refine. 2023-12-22 22:22:04 -08:00
8147d8669e Dropped another js tool. 2023-12-22 20:57:59 -08:00
c475681b0e Dropped js replace tool. 2023-12-22 20:46:23 -08:00
3c0f249b71 Switch more things to new script. 2023-12-22 20:22:30 -08:00
9bb8a3e28e Switching more into importation. 2023-12-22 20:01:49 -08:00
2c726611a0 Progress towards ninja build. 2023-12-22 18:31:38 -08:00
16e15d6f07 Fix 2023-12-22 17:05:44 -08:00
d3b2bbb6f0 Fix 2023-12-22 16:30:20 -08:00
d73d340271 Improved. 2023-12-22 16:13:15 -08:00
e92130391c Enhance windows. 2023-12-22 15:32:33 -08:00
ab6f020bbc More incremental. 2023-12-22 14:48:59 -08:00
f882c97f60 Fixed gen dependencies. 2023-12-22 14:33:08 -08:00
ca05d3b6b0 Switch to importation tool, regression.
Regresses proper depedencies temporarily.
2023-12-22 14:00:17 -08:00
1588e20247 Fix permissions. 2023-12-21 17:30:25 -08:00
74bfc5dcbc Add some process functions to posix. 2023-12-20 14:30:28 -08:00
0a102d9785 Fix. 2023-12-16 09:16:46 -08:00
c31a2cd669 Adding pico ADC. 2023-12-16 00:37:37 -08:00
d02499511b Switched to newer arduino-cli for build/flash. 2023-12-09 11:34:11 -08:00
1cd785241b Bumping go runtime version. 2023-12-08 20:03:36 -08:00
e39ab94fdd Switch pico-ice build to ninja.
Automate submodule setup.
2023-12-08 19:52:35 -08:00
b2e1556588 Tweaking modules. 2023-12-08 19:28:49 -08:00
14d9053a3d Tweak build. 2023-12-08 19:18:20 -08:00
8dfcef572b Bumping version + getting ready to push pico-ice version. 2023-12-08 19:11:54 -08:00
2c045cfd19 Tweak build. 2023-12-08 18:40:27 -08:00
7ec27fbeef Attempting to add pico-ice to website. 2023-12-08 18:36:26 -08:00
7f49b3503d Fix bindings bug. 2023-12-08 14:44:45 -08:00
b8229480fa Moving ice words into their own vocab. 2023-12-03 22:23:25 -08:00
efd0180a24 Adding more pico-ice bindings. 2023-12-03 22:08:11 -08:00
c40a2f5c6f Adding initial pico-ice support. 2023-12-03 19:57:14 -08:00
fa56ecf59d Adding U<. 2023-11-11 14:46:27 -08:00
564a8fc68b Pulled interrupts into an optional module. 2023-07-08 11:57:20 -07:00
fc7175d488 Pull RMT into an optional module, refactor. 2023-07-08 10:21:13 -07:00
8d72804378 Fix documentation. 2023-07-07 17:19:59 -07:00
235a4a0c45 Fix optionals, bump version.
Tried on real hardware.
2023-07-07 17:16:20 -07:00
998d619355 Fix bug in structures that don't use TYPER sizes.
Thanks Frank!
2023-07-07 16:16:00 -07:00
a5f9ca1b35 Fixed some bugs with build in modules. 2023-07-06 22:55:18 -07:00
7b74cddf2d More module decomposition.
Needs much more on device testing.
2023-07-05 22:58:03 -07:00
ea1217a162 Fix up optionals, pull out oled. 2023-07-05 21:41:21 -07:00
6884898cb1 Peel off assemblers into optional module.
Not sufficiently tested.
2023-07-05 15:00:59 -07:00
2a673c7378 fix 2023-06-19 14:51:17 -07:00
decebd0dd2 Fix bug. 2023-06-18 21:44:06 -07:00
c9abb34f2b More upload/download. 2023-06-18 20:59:24 -07:00
2e28098c53 More session state with web. 2023-06-18 20:24:37 -07:00
2ee77a2572 Tweak windows constants for clarity + missing range value. 2023-05-29 11:06:45 -07:00
60447dd11a refactor 2023-05-26 12:14:31 -07:00
a50a33cae8 refactor 2023-05-26 12:12:52 -07:00
0f47287dfa Improving path-join. 2023-05-25 19:35:13 -07:00
8c31cbd694 Adding Oofda & Poke, fix copyright notice.
Adding an experimental Object Sytem (Oofda).
Adding an experimental DI Framework (Poke).
2023-05-24 21:00:40 -07:00
8e46c227ac Bump version. 2023-05-19 23:33:45 -07:00
18e83d4dc3 Fixing web bug with RSHIFT. 2023-05-19 23:33:14 -07:00
0c113062c6 Bumping version. 2023-05-05 00:49:13 -07:00
bab72b79a7 Fix LOOP/+LOOP bug.
Forth-83 and after pick a more useful definition of how
LOOP and +LOOP should decide termination:
if the last step traversed between limit-1 and limit.

This allows for signed or unsigned loops with the same construct.

Updating to this behavior + adding test + fixing old test
that didn't match gforth.
2023-05-05 00:46:18 -07:00
705e839c62 Fix overlap of system variables for float stack. 2023-04-23 21:44:37 -07:00
c43cbfd9d9 Replumbing timers working around Arduino change.
Bumping version number and changing example.

Interrupt WDT now makes example flaky so changing.
2023-04-17 18:10:20 -07:00
c7dcbbef36 Fixing TIMG constant.
Thanks for catching mpetremann!
2023-04-08 07:22:13 -07:00
fb3db70da6 Adding text size. 2023-02-24 21:25:54 -08:00
244f16b898 Handle multiple script tags. 2023-02-24 21:04:26 -08:00
da324bdf70 Adding script load.
Still need to enhance to support script src.
2023-02-21 21:08:03 -08:00
d2c62a35b9 Make it possible to defer start, boost web memory. 2023-02-20 18:11:45 -08:00
5a40463464 Implicit ls in current directory. 2023-02-06 20:34:50 -08:00
44d550dab0 Simplify. 2023-02-05 12:41:27 -08:00
db72474bcb Label exceptions. 2023-02-05 12:22:12 -08:00
2b05d7794e Refactor inching towards risc-v fault handling. 2023-02-05 11:58:48 -08:00
9ef1ea9f90 Clean up include, autoboot, split windows, shorten start.
Drop startup timeout to 100ms.
Clean up exceptions in include.
Cleanup stack in autoboot.
Split out windows into a second string, to work around overflow issue.
2023-01-22 16:44:42 -08:00
40400b873e Cleaning up throw values around division + faults. 2023-01-22 15:08:14 -08:00
cfd70d6712 Make thrown value match standards. 2023-01-22 12:16:57 -08:00
f82e423fb4 Add abort, abort" and start on testing throw values. 2023-01-22 12:06:58 -08:00
5c918d91f6 Bump version number. 2023-01-21 21:28:55 -08:00
fe87f1574c Adding platform detection opcodes + fix assembler bug.
Adding flags to allow runtime detection of different esp32 models,
riscv vs xtensa, and psram.

Use this to conditionally compile hook for relevant assemblers.
2023-01-21 21:27:29 -08:00
adfd238ee2 Updating build to hopefully allow OSX builds.
dlsym opcode modified so that 0 for library is converted
to RTLD_DEFAULT as the two don't match on Darwin.

Made errno an opcode, as previous method depended on Linux internals.
[1] https://opensource.apple.com/source/xnu/xnu-201/osfmk/libsa/errno.h.auto.html
[2] https://pubs.opengroup.org/onlinepubs/9699919799/functions/errno.html
Placed errno in internals and then alias inside posix vocabulary,
as it seemed a waste to have another builtin stub for one symbol.
Arguably maybe dlsym should be that way too, but leaving for now.

Added OS make variable to conditionally set flags.
Set stripping / minimization options based on it.

Based off of
https://github.com/flagxor/ueforth/pull/3
Thanks Ulrich!
2023-01-21 20:11:42 -08:00
6ed9c2141e Use proper name. 2023-01-20 23:12:08 -08:00
b87d21e548 Fix bug in strcase=. 2023-01-16 13:21:38 -08:00
5189669562 Make key return -1 on EOF. 2023-01-15 19:26:56 -08:00
d78953151a Tweaking include order to avoid b0, b1, etc. macro clash, bump version. 2023-01-14 23:14:01 -08:00
75d9185027 Align PARK/UNPARK with THROW/CATCH. 2023-01-14 22:53:30 -08:00
2f79192ea0 Refactor fault handling. 2023-01-14 22:28:38 -08:00
f8cfaedc84 Adding tests for faults. 2023-01-14 18:31:33 -08:00
3dcd421576 Windows Ctrl-C working. 2023-01-14 17:38:58 -08:00
fc6c771d86 Merge branch 'main' into win_break 2023-01-14 15:06:56 -08:00
3ba96a284f Bump version. 2023-01-14 15:06:25 -08:00
106fdcb63d Shunt out more things for camera + bluetooth when not there. 2023-01-14 15:05:44 -08:00
600e82d67e Add fault handling for ESP32, ESP32-S2, and ESP32-S3.
Also bump the version.
2023-01-04 21:45:26 -08:00
b155e49a63 Intercept division by zero with a fault handler. 2023-01-04 21:17:49 -08:00
3d1cf4b93c Making [IF] [THEN] work at console, bumping version. 2023-01-03 21:01:51 -08:00
a1a934397d Fix branch decoding. 2023-01-02 21:08:53 -08:00
1b52ba02d1 trying to make ctrl-c work on windows. 2022-12-31 23:02:15 -08:00
b720575fb2 Adding exception handling for windows. 2022-12-31 22:13:19 -08:00
1c500c2233 Simplify terminate + bye + fix build. 2022-12-31 21:02:04 -08:00
d60606b4c8 Fix bug in signals for posix. 2022-12-31 19:26:20 -08:00
5afdbf0423 Adding posix signal handling. 2022-12-31 16:21:43 -08:00
f77a65ce3c Add more to makefile. 2022-11-25 16:53:10 -08:00
d801d14540 Updating makefile and readme. 2022-11-25 16:52:13 -08:00
4052ebcb81 Drop flag causing compatibilities issues on raspberry pi w/ gcc. 2022-11-25 13:48:53 -08:00
595ed9e829 Ameliorate race condition with web import. 2022-11-19 22:37:29 -08:00
80fb47f87b Fix name clash between visual vocab + name in posix grapihcs. 2022-11-19 22:05:55 -08:00
d5675806fc More bindings. 2022-11-19 00:54:45 -08:00
7758bd3ba7 Fix picker bug. 2022-11-19 00:31:46 -08:00
e8bb29eff7 Various improvments. 2022-11-18 23:42:03 -08:00
e9181479fc Improving mouse and tasks. 2022-11-18 22:53:09 -08:00
8ee1eafef6 Adding import + fix bug in web Find. 2022-11-18 20:11:19 -08:00
5437048f33 Change audio approach. 2022-11-17 23:20:40 -08:00
dd607401e4 Tweaking audio and web yield logic. 2022-11-17 22:55:21 -08:00
279b391a28 Handle return value better in JS bindings. 2022-11-17 20:42:20 -08:00
9e1aaedf12 Refine jsword. 2022-11-16 21:05:03 -08:00
85bb2942be Refine jseval words. 2022-11-15 22:56:40 -08:00
31947f712a Refactor jseval words. 2022-11-15 22:52:38 -08:00
a2232d49f1 Refactor, starting audio. 2022-11-15 22:39:17 -08:00
6f054fa39f Adding key iteration. 2022-11-15 21:16:33 -08:00
1baa1aa76c Adding getItem/setItem web bindings. 2022-11-14 21:26:23 -08:00
9090fc4776 Run putty in the background. 2022-11-12 08:20:00 -08:00
204f74219f Add shortcut for putty. 2022-11-12 08:13:05 -08:00
447c63a6f0 Adding RISC-V assembler/disassembler.
Probably should be conditionally added for ESP32-C3 only.
2022-11-11 23:25:34 -08:00
4751b31c40 Fixing a bug in CASE. 2022-11-08 19:42:44 -08:00
23ec00d7cd Bump version number. 2022-11-07 22:52:57 -08:00
64f002b127 Add EXTUI, fix call addresses. 2022-11-07 22:52:33 -08:00
10ad2e2a52 Adding more graphics operations. 2022-11-07 22:22:50 -08:00
c1692b8039 More fiddling with call addresses. 2022-10-22 09:54:01 -07:00
d9d515861b Fix call. 2022-10-22 09:29:13 -07:00
6b597aebc2 More xtensa assembler improvements. 2022-10-21 23:06:36 -07:00
32f66894c0 Fix disassembly more. 2022-10-21 21:59:25 -07:00
624dab60a9 Add byte emission. 2022-10-21 21:44:49 -07:00
742b8f9cb0 Adding address to disassembly. 2022-10-21 21:09:45 -07:00
cd1e0d9ee9 Fixing up vocabulary layering for assembler. 2022-10-21 21:05:14 -07:00
e69c1dba0c WIP Xtensa Assembler/Disassembler. 2022-10-21 20:07:26 -07:00
4dd55a382c Fix EAGAIN issue. 2022-10-21 15:02:12 -07:00
e28b4f0130 Adding WIP alternate case approach. 2022-10-16 13:56:09 -07:00
97ab39160a Fixed Serial2 issue for ESP32C3, added arduino-build. 2022-10-08 13:02:38 -07:00
1826a75cd0 Adding a USER_VOCABULARIES hook. 2022-10-07 20:48:05 -07:00
30665011df Probably better definition of CASE. 2022-09-23 22:49:37 -07:00
58f5cb249d Simple CASE implementation. 2022-09-23 22:42:05 -07:00
c49bb6571e Fixing up website. 2022-09-05 22:01:39 -07:00
bc12a4bf72 Fix bug in ls for esp32. 2022-09-05 21:45:21 -07:00
234d85bf71 Add mkdir, cd, and more, refactor. 2022-09-05 21:25:46 -07:00
0dbe262abf Refining file handling. 2022-09-05 18:31:44 -07:00
8cd205a9a5 Added mv, fixed rename of esp32, and added touch. 2022-09-05 17:29:41 -07:00
a6dddb83e1 More shell type commands. 2022-09-05 17:18:01 -07:00
3be3f23d8b Adding cat. 2022-09-05 17:01:03 -07:00
cadc350d30 Fixing issue with opening existing file in editor. 2022-09-05 16:52:16 -07:00
b7d47cead0 Fixed code example. 2022-09-04 23:57:38 -07:00
109b6c064c Fixing up code words more. 2022-09-04 23:32:34 -07:00
fbfbc549ff Add non-functional code example for xtensa. 2022-09-04 17:45:47 -07:00
393b54d873 Fixup see for code words. 2022-09-04 17:05:06 -07:00
8bed92bef9 Start of adding code word support. 2022-09-04 16:58:11 -07:00
17a8dbbf59 Fixed up bterm to work on tighter devices.
Added way to RELINQUISH part of the forth heap.
key? for bluetooth serial.
2022-09-04 14:39:28 -07:00
b4437658bf Improving dump. 2022-09-04 11:35:38 -07:00
75d14d6bdd Making httpd body handling better. 2022-08-28 22:27:10 -07:00
1434760820 Make httpd headers case insensitive. 2022-08-28 20:40:41 -07:00
cdc3b03fe9 Make httpd more correct. 2022-08-28 20:07:23 -07:00
3c2677c4fe Add more camera docs. 2022-08-14 14:42:53 -07:00
dfd519ad12 Added more camera bindings. 2022-08-14 14:13:36 -07:00
d7d5918c5a Update sockets docs. 2022-08-12 23:40:57 -07:00
26638fd68d Tweak udp. 2022-08-12 23:22:46 -07:00
bcaa6da021 Tweak closing. 2022-08-12 23:15:17 -07:00
1031c52e9b Tweak 2022-08-12 23:14:18 -07:00
b0a93c7477 Adding curl-lite example. 2022-08-12 22:47:38 -07:00
bbf400d656 Bumping version. 2022-08-12 21:52:43 -07:00
1ed8d074ae Adding visual editor. 2022-08-12 21:52:11 -07:00
40f45e47e3 Tweak sockets. 2022-08-12 16:54:50 -07:00
b1612c116b Tweak blink rate. 2022-08-12 13:41:38 -07:00
2f75fd7ae0 Tweaking scrolling. 2022-08-12 09:11:40 -07:00
5a676af894 Fixing up cursor and color handling. 2022-08-11 23:33:08 -07:00
dce538da4a Adding host lookup. 2022-08-11 00:07:46 -07:00
00c6a87228 Adding more UDP support + example. 2022-08-10 23:41:40 -07:00
71109e3880 Speed up colors more. 2022-08-10 19:30:43 -07:00
356a9204a4 Tweak keyboard font. 2022-08-09 23:41:42 -07:00
5277b6dbbb Adding many, but not all ansi escape codes to web. 2022-08-09 23:23:56 -07:00
200 changed files with 9741 additions and 2370 deletions

1
.gitignore vendored
View File

@ -1 +1,2 @@
out
build.ninja

10
.gitmodules vendored Normal file
View File

@ -0,0 +1,10 @@
[submodule "pico-ice/pico-sdk"]
path = pico-ice/pico-sdk
url = https://github.com/raspberrypi/pico-sdk
shallow = true
ignore = dirty
[submodule "pico-ice/pico-ice-sdk"]
path = pico-ice/pico-ice-sdk
url = https://github.com/tinyvision-ai-inc/pico-ice-sdk
shallow = true
ignore = dirty

25
BUILD Normal file
View File

@ -0,0 +1,25 @@
# Copyright 2023 Bradley D. Nelson
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
SetVersions(
version='7.0.7.21',
stable='7.0.6.19',
old_stable='7.0.5.4')
Include('posix')
Include('windows')
Include('web')
Include('pico-ice')
Include('esp32')
Include('site')

593
Makefile
View File

@ -1,593 +0,0 @@
# Copyright 2021 Bradley D. Nelson
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
VERSION=7.0.7.1
STABLE_VERSION=7.0.6.19
OLD_STABLE_VERSION=7.0.5.4
REVISION=$(shell git rev-parse HEAD | head -c 20)
REVSHORT=$(shell echo $(REVISION) | head -c 7)
OUT = out
GEN = $(OUT)/gen
RES = $(OUT)/resources
WEB = $(OUT)/web
POSIX = $(OUT)/posix
WINDOWS = $(OUT)/windows
ESP32 = $(OUT)/esp32
ESP32_SIM = $(OUT)/esp32-sim
DEPLOY = $(OUT)/deploy
CFLAGS_COMMON = -O2 -I ./ -I $(OUT)
CFLAGS_MINIMIZE = \
-s \
-DUEFORTH_MINIMAL \
-fno-exceptions \
-ffreestanding \
-fno-stack-protector \
-fomit-frame-pointer \
-mno-stack-arg-probe \
-fno-ident -Wl,--build-id=none \
-ffunction-sections -fdata-sections \
-fmerge-all-constants
CFLAGS = $(CFLAGS_COMMON) \
$(CFLAGS_MINIMIZE) \
-std=c++11 \
-Wall \
-Werror \
-no-pie \
-Wl,--gc-sections
STRIP_ARGS = -S \
--strip-unneeded \
--remove-section=.note.gnu.gold-version \
--remove-section=.comment \
--remove-section=.note \
--remove-section=.note.gnu.build-id \
--remove-section=.note.ABI-tag
LIBS=-ldl
WIN_CFLAGS = $(CFLAGS_COMMON) \
-I "c:/Program Files (x86)/Microsoft SDKs/Windows/v7.1A/Include" \
-I "c:/Program Files (x86)/Microsoft Visual Studio/2019/Community/VC/Tools/MSVC/14.28.29333/include" \
-I "c:/Program Files (x86)/Windows Kits/10/Include/10.0.19041.0/ucrt"
WIN_LFLAGS32 = /LIBPATH:"c:/Program Files (x86)/Microsoft SDKs/Windows/v7.1A/Lib" \
/LIBPATH:"c:/Program Files (x86)/Microsoft Visual Studio/2019/Community/VC/Tools/MSVC/14.28.29333/lib/x86" \
/LIBPATH:"c:/Program Files (x86)/Windows Kits/10/Lib/10.0.19041.0/ucrt/x86" \
$(WIN_LIBS)
WIN_LFLAGS64 = /LIBPATH:"c:/Program Files (x86)/Microsoft SDKs/Windows/v7.1A/Lib/x64" \
/LIBPATH:"c:/Program Files (x86)/Microsoft Visual Studio/2019/Community/VC/Tools/MSVC/14.28.29333/lib/x64" \
/LIBPATH:"c:/Program Files (x86)/Windows Kits/10/Lib/10.0.19041.0/ucrt/x64" \
$(WIN_LIBS)
WIN_LIBS=user32.lib
TARGETS = posix_target \
web_target \
esp32_target \
esp32_sim_target
TESTS = posix_tests web_tests esp32_sim_tests
LSQ = ls 2>/dev/null
PROGFILES = /mnt/c/Program Files (x86)
MSVS = "${PROGFILES}/Microsoft Visual Studio"
MSKITS = "${PROGFILES}/Windows Kits"
CL32 = "$(shell $(LSQ) ${MSVS}/*/*/VC/Tools/MSVC/*/bin/Hostx86/x86/cl.exe | head -n 1)"
CL64 = "$(shell $(LSQ) ${MSVS}/*/*/VC/Tools/MSVC/*/bin/Hostx86/x64/cl.exe | head -n 1)"
LINK32 = "$(shell $(LSQ) ${MSVS}/*/*/VC/Tools/MSVC/*/bin/Hostx86/x86/link.exe | head -n 1)"
LINK64 = "$(shell $(LSQ) ${MSVS}/*/*/VC/Tools/MSVC/*/bin/Hostx86/x64/link.exe | head -n 1)"
RC32 = "$(shell $(LSQ) ${MSKITS}/*/bin/*/x86/rc.exe | head -n 1)"
RC64 = "$(shell $(LSQ) ${MSKITS}/*/bin/*/x64/rc.exe | head -n 1)"
D8 = "$(shell $(LSQ) ${HOME}/src/v8/v8/out/x64.release/d8)"
# Selectively enable windows if tools available
DEPLOYABLE := 1
ifneq ("", $(CL32))
ifneq ("", $(RC32))
TARGETS += win32_target
TESTS += win32_tests
else
$(warning "Missing Visual Studio rc.exe skipping 32-bit Windows.")
DEPLOYABLE := 0
endif
else
$(warning "Missing Visual Studio cl.exe skipping 32-bit Windows.")
DEPLOYABLE := 0
endif
ifneq ("", $(CL64))
ifneq ("", $(RC64))
TARGETS += win64_target
TESTS += win64_tests
else
$(warning "Missing Visual Studio rc.exe skipping 64-bit Windows.")
DEPLOYABLE := 0
endif
else
$(warning "Missing Visual Studio cl.exe skipping 64-bit Windows.")
DEPLOYABLE := 0
endif
# Decide if we can deploy.
DEPLOY_TARGETS =
ifeq (1, $(DEPLOYABLE))
DEPLOY_TARGETS := $(DEPLOY)/app.yaml
else
$(warning "Missing some platforms skipping deployment build.")
endif
WEB_D8_TESTS =
# Decide if we have d8.
ifneq ("", $(D8))
WEB_D8_TESTS += sanity_test_web
endif
all: targets tests $(DEPLOY_TARGETS)
fast: posix esp32_sim esp32
targets: $(TARGETS)
tests: $(TESTS)
clean:
rm -rf $(OUT)
# ---- TESTS ----
posix_tests: unit_tests_posix see_all_test_posix save_restore_test
win32_tests: unit_tests_win32
win64_tests: unit_tests_win64
web_tests: $(WEB_D8_TESTS)
esp32_tests:
esp32_sim_tests: unit_tests_esp32_sim see_all_test_esp32_sim sizes
# ---- UNIT TESTS ----
unit_tests_posix: $(POSIX)/ueforth common/all_tests.fs
$^
unit_tests_esp32_sim: \
$(ESP32_SIM)/Esp32forth-sim \
common/ansi.fs \
common/all_tests.fs
echo "include $(word 2,$^) include $(word 3,$^) \n1 terminate" | $<
unit_tests_win32: $(WINDOWS)/uEf32.exe common/all_tests.fs
wine $^
unit_tests_win64: $(WINDOWS)/uEf64.exe common/all_tests.fs
wine $^
# ---- OTHER TESTS ----
see_all_test_posix: $(POSIX)/ueforth
echo internals see-all bye | $< >/dev/null
see_all_test_esp32_sim: $(ESP32_SIM)/Esp32forth-sim
echo internals see-all bye | $< >/dev/null
save_restore_test: $(POSIX)/ueforth
echo ': square dup * ; save /tmp/save_restore_test.bin bye' | $< >/dev/null
echo 'restore /tmp/save_restore_test.bin 4 square 16 - posix sysexit' | $< >/dev/null
sizes: $(ESP32_SIM)/Esp32forth-sim
echo internals size-all bye | $< | tools/memuse.py >$(ESP32_SIM)/sizes.txt
sanity_test_web: $(WEB)/ueforth.js
echo '120 3 + . cr bye' | $(D8) $< | tools/check_web_sanity.js
# ---- GENERATED ----
$(GEN):
mkdir -p $@
COMMON_PHASE1 = common/comments.fs \
common/boot.fs \
common/io.fs \
common/conditionals.fs \
common/vocabulary.fs \
common/floats.fs \
common/structures.fs
COMMON_PHASE1e = common/comments.fs \
common/tier2a_forth.fs \
common/boot.fs \
common/tier2b_forth.fs \
common/io.fs \
common/conditionals.fs \
common/vocabulary.fs \
common/floats.fs \
common/structures.fs
COMMON_PHASE2 = common/utils.fs common/locals.fs
COMMON_FILETOOLS = common/tasks.fs common/streams.fs \
common/filetools.fs common/including.fs \
common/blocks.fs
COMMON_DESKTOP = common/ansi.fs common/desktop.fs \
common/graphics.fs common/graphics_utils.fs common/heart.fs
POSIX_BOOT = $(COMMON_PHASE1) \
posix/posix.fs posix/allocation.fs posix/termios.fs \
$(COMMON_PHASE2) $(COMMON_FILETOOLS) $(COMMON_DESKTOP) \
posix/x11.fs \
posix/graphics.fs \
posix/sockets.fs posix/telnetd.fs posix/httpd.fs posix/web_interface.fs \
posix/autoboot.fs \
common/fini.fs
$(GEN)/posix_boot.h: tools/source_to_string.js $(POSIX_BOOT) | $(GEN)
$< boot $(VERSION) $(REVISION) $(POSIX_BOOT) >$@
WINDOWS_BOOT = $(COMMON_PHASE1) \
windows/windows_core.fs \
windows/windows_files.fs \
windows/windows_console.fs \
windows/windows_user.fs \
windows/windows_gdi.fs \
windows/windows_messages.fs \
windows/allocation.fs \
$(COMMON_PHASE2) $(COMMON_FILETOOLS) $(COMMON_DESKTOP) \
windows/graphics.fs \
posix/autoboot.fs \
common/fini.fs
$(GEN)/windows_boot.h: tools/source_to_string.js $(WINDOWS_BOOT) | $(GEN)
$< -win boot $(VERSION) $(REVISION) $(WINDOWS_BOOT) >$@
ESP32_BOOT = $(COMMON_PHASE1) \
esp32/allocation.fs \
$(COMMON_PHASE2) $(COMMON_FILETOOLS) \
esp32/bindings.fs esp32/platform.fs \
posix/httpd.fs posix/web_interface.fs esp32/web_interface.fs \
esp32/registers.fs esp32/timers.fs \
esp32/bterm.fs posix/telnetd.fs \
esp32/camera.fs esp32/camera_server.fs \
esp32/autoboot.fs common/fini.fs
$(GEN)/esp32_boot.h: tools/source_to_string.js $(ESP32_BOOT) | $(GEN)
$< boot $(VERSION) $(REVISION) $(ESP32_BOOT) >$@
$(GEN)/dump_web_opcodes: \
web/dump_web_opcodes.c \
common/tier0_opcodes.h \
common/tier1_opcodes.h \
common/bits.h \
common/floats.h | $(GEN)
$(CXX) $(CFLAGS) $< -o $@
$(GEN)/web_cases.js: $(GEN)/dump_web_opcodes | $(GEN)
$< cases >$@
$(GEN)/web_dict.js: $(GEN)/dump_web_opcodes | $(GEN)
$< dict >$@
$(GEN)/web_sys.js: $(GEN)/dump_web_opcodes | $(GEN)
$< sys >$@
WEB_BOOT = $(COMMON_PHASE1e) \
web/platform.fs \
$(COMMON_PHASE2) \
web/fini.fs
$(GEN)/web_boot.js: tools/source_to_string.js $(WEB_BOOT) | $(GEN)
$< -web boot $(VERSION) $(REVISION) $(WEB_BOOT) >$@
# ---- RESOURCES ----
$(RES):
mkdir -p $@
$(RES)/eforth16x16.png: images/eforth.png | $(RES)
convert -resize 16x16 $< $@
$(RES)/eforth32x32.png: images/eforth.png | $(RES)
convert -resize 32x32 $< $@
$(RES)/eforth48x48.png: images/eforth.png | $(RES)
convert -resize 48x48 $< $@
$(RES)/eforth256x256.png: images/eforth.png | $(RES)
convert -resize 256x256 $< $@
ICON_SIZES = $(RES)/eforth256x256.png \
$(RES)/eforth48x48.png \
$(RES)/eforth32x32.png \
$(RES)/eforth16x16.png
$(RES)/eforth.ico: $(ICON_SIZES)
convert $^ $< $@
$(RES)/ueforth_res32.res: windows/ueforth.rc $(RES)/eforth.ico
$(RC32) /fo $@ $<
$(RES)/ueforth_res64.res: windows/ueforth.rc $(RES)/eforth.ico
$(RC64) /fo $@ $<
# ---- WEB ----
web: web_target web_tests
web_target: $(WEB)/terminal.html $(WEB)/ueforth.js
$(WEB):
mkdir -p $(WEB)
$(WEB)/terminal.html: web/terminal.html | $(WEB)
cp $< $@
$(WEB)/ueforth.js: \
web/fuse_web.js \
web/web.template.js \
$(GEN)/web_boot.js \
$(GEN)/web_dict.js \
$(GEN)/web_cases.js \
$(GEN)/web_sys.js | $(WEB)
$^ >$@
# ---- POSIX ----
posix: posix_target posix_tests
posix_target: $(POSIX)/ueforth
$(POSIX):
mkdir -p $@
$(POSIX)/ueforth: \
posix/main.c \
common/tier0_opcodes.h \
common/tier1_opcodes.h \
common/tier2_opcodes.h \
common/calls.h \
common/calling.h \
common/floats.h \
common/interp.h \
common/bits.h \
common/core.h \
$(GEN)/posix_boot.h | $(POSIX)
$(CXX) $(CFLAGS) $< -o $@ $(LIBS)
strip $(STRIP_ARGS) $@
# ---- WINDOWS ----
win32: win32_target win32_tests
win64: win64_target win64_tests
win32_target: $(WINDOWS)/uEf32.exe
win64_target: $(WINDOWS)/uEf64.exe
$(WINDOWS):
mkdir -p $@
$(WINDOWS)/uEf32.obj: \
windows/main.c \
common/tier0_opcodes.h \
common/tier1_opcodes.h \
common/tier2_opcodes.h \
common/calls.h \
common/calling.h \
common/floats.h \
common/bits.h \
common/core.h \
windows/interp.h \
$(GEN)/windows_boot.h | $(WINDOWS)
$(CL32) /c /Fo$@ $(WIN_CFLAGS) $<
$(WINDOWS)/uEf32.exe: \
$(WINDOWS)/uEf32.obj \
$(RES)/ueforth_res32.res | $(WINDOWS)
$(LINK32) /OUT:$@ $(WIN_LFLAGS32) $^
$(WINDOWS)/uEf64.obj: \
windows/main.c \
common/tier0_opcodes.h \
common/tier1_opcodes.h \
common/tier2_opcodes.h \
common/calls.h \
common/calling.h \
common/floats.h \
common/bits.h \
common/core.h \
windows/interp.h \
$(GEN)/windows_boot.h | $(WINDOWS)
$(CL64) /c /Fo$@ $(WIN_CFLAGS) $<
$(WINDOWS)/uEf64.exe: \
$(WINDOWS)/uEf64.obj \
$(RES)/ueforth_res64.res | $(WINDOWS)
$(LINK64) /OUT:$@ $(WIN_LFLAGS64) $^
# ---- ESP32-SIM ----
esp32_sim: esp32_sim_target esp32_sim_tests
esp32_sim_target: $(ESP32_SIM)/Esp32forth-sim
$(ESP32_SIM):
mkdir -p $@
$(GEN)/print-esp32-builtins: \
esp32/print-builtins.cpp esp32/builtins.h | $(GEN)
$(CXX) $(CFLAGS) $< -o $@
$(GEN)/esp32_sim_opcodes.h: $(GEN)/print-esp32-builtins | $(GEN)
$< >$@
$(ESP32_SIM)/Esp32forth-sim: \
esp32/sim_main.cpp \
esp32/main.cpp \
common/tier0_opcodes.h \
common/tier1_opcodes.h \
common/tier2_opcodes.h \
common/floats.h \
common/calling.h \
common/floats.h \
common/bits.h \
common/core.h \
common/interp.h \
$(GEN)/esp32_boot.h \
$(GEN)/esp32_sim_opcodes.h | $(ESP32_SIM)
$(CXX) $(CFLAGS) $< -o $@
strip $(STRIP_ARGS) $@
# ---- ESP32 ----
esp32: esp32_target esp32_sim esp32_tests esp32_sim_tests
esp32_target: $(ESP32)/ESP32forth/ESP32forth.ino
$(ESP32)/ESP32forth:
mkdir -p $@
ESP32_PARTS = tools/replace.js \
esp32/template.ino \
common/tier0_opcodes.h \
common/tier1_opcodes.h \
common/tier2_opcodes.h \
common/floats.h \
common/calling.h \
common/bits.h \
common/core.h \
common/interp.h \
esp32/options.h \
esp32/builtins.h \
esp32/builtins.cpp \
esp32/main.cpp \
$(GEN)/esp32_boot.h
$(ESP32)/ESP32forth/ESP32forth.ino: $(ESP32_PARTS) | $(ESP32)/ESP32forth
cat esp32/template.ino | tools/replace.js \
VERSION=$(VERSION) \
REVISION=$(REVISION) \
tier0_opcodes=@common/tier0_opcodes.h \
tier1_opcodes=@common/tier1_opcodes.h \
tier2_opcodes=@common/tier2_opcodes.h \
calling=@common/calling.h \
floats=@common/floats.h \
bits=@common/bits.h \
core=@common/core.h \
interp=@common/interp.h \
options=@esp32/options.h \
builtins.h=@esp32/builtins.h \
builtins.cpp=@esp32/builtins.cpp \
main.cpp=@esp32/main.cpp \
boot=@$(GEN)/esp32_boot.h \
>$@
# ---- PACKAGE ----
$(ESP32)/ESP32forth.zip: $(ESP32)/ESP32forth/ESP32forth.ino
cd $(ESP32) && rm -f ESP32forth.zip && zip -r ESP32forth.zip ESP32forth
# ---- Publish to Archive ----
ARCHIVE=gs://eforth/releases
GSUTIL=CLOUDSDK_CORE_PROJECT=eforth gsutil
GSUTIL_CP=$(GSUTIL) \
-h "Cache-Control:public, max-age=60" \
cp -a public-read
publish-esp32: $(ESP32)/ESP32forth.zip
$(GSUTIL_CP) \
$(ESP32)/ESP32forth.zip \
$(ARCHIVE)/ESP32forth-$(VERSION)-$(REVSHORT).zip
$(GSUTIL_CP) \
$(ESP32)/ESP32forth.zip \
$(ARCHIVE)/ESP32forth-$(VERSION).zip
publish-linux: $(POSIX)/ueforth
$(GSUTIL_CP) \
$(POSIX)/ueforth \
$(ARCHIVE)/ueforth-$(VERSION)-$(REVSHORT).linux
$(GSUTIL_CP) \
$(POSIX)/ueforth \
$(ARCHIVE)/ueforth-$(VERSION).linux
publish-web: $(WEB)/ueforth.js
$(GSUTIL_CP) \
$(WEB)/ueforth.js \
$(ARCHIVE)/ueforth-$(VERSION)-$(REVSHORT).js
$(GSUTIL_CP) \
$(WEB)/ueforth.js \
$(ARCHIVE)/ueforth-$(VERSION).js
publish-windows: $(WINDOWS)/uEf32.exe $(WINDOWS)/uEf64.exe
$(GSUTIL_CP) \
$(WINDOWS)/uEf32.exe \
$(ARCHIVE)/uEf32-$(VERSION)-$(REVSHORT).exe
$(GSUTIL_CP) \
$(WINDOWS)/uEf32.exe \
$(ARCHIVE)/uEf32-$(VERSION).exe
$(GSUTIL_CP) \
$(WINDOWS)/uEf64.exe \
$(ARCHIVE)/uEf64-$(VERSION)-$(REVSHORT).exe
$(GSUTIL_CP) \
$(WINDOWS)/uEf64.exe \
$(ARCHIVE)/uEf64-$(VERSION).exe
publish-index: | $(GEN)
$(GSUTIL) ls -l gs://eforth/releases | tools/webindex.py >$(GEN)/archive.html
$(GSUTIL_CP) \
$(GEN)/archive.html \
gs://eforth/releases/archive.html
publish: publish-esp32 publish-linux publish-web publish-windows publish-index
# ---- DEPLOY ----
$(DEPLOY):
mkdir -p $@
REPLACE = tools/replace.js \
HEAD=@site/head.html \
COMMON=@site/common.html \
POSIX_COMMON=@site/posix_common.html \
DESKTOP_COMMON=@site/desktop_common.html \
MENU=@site/menu.html \
VERSION=${VERSION} \
STABLE_VERSION=${STABLE_VERSION} \
OLD_STABLE_VERSION=${OLD_STABLE_VERSION}
UE_REPLACE = $(REPLACE) FORTH=uEForth
ESP_REPLACE = $(REPLACE) FORTH=ESP32forth
$(DEPLOY)/app.yaml: $(RES)/eforth.ico \
$(wildcard site/*.html) \
site/static/eforth.css \
site/app.yaml \
site/eforth.go \
$(TARGETS) | $(DEPLOY)
rm -rf $(DEPLOY)/
mkdir -p $(DEPLOY)
cp -r site/static $(DEPLOY)/static
cp $(RES)/eforth.ico $(DEPLOY)/static/favicon.ico
cp site/*.go $(DEPLOY)/
cp site/*.yaml $(DEPLOY)/
cp site/.gcloudignore $(DEPLOY)
cp out/web/ueforth.js $(DEPLOY)/
cat site/web.html | $(ESP_REPLACE) >$(DEPLOY)/web.html
cat site/ESP32forth.html | $(ESP_REPLACE) >$(DEPLOY)/ESP32forth.html
cat site/index.html | $(UE_REPLACE) >$(DEPLOY)/index.html
cat site/linux.html | $(UE_REPLACE) >$(DEPLOY)/linux.html
cat site/windows.html | $(UE_REPLACE) >$(DEPLOY)/windows.html
cat site/internals.html | $(UE_REPLACE) >$(DEPLOY)/internals.html
cat site/classic.html | $(UE_REPLACE) >$(DEPLOY)/classic.html
deploy: all
cd out/deploy && gcloud app deploy -q --project esp32forth *.yaml
cd out/deploy && gcloud app deploy -q --project eforth *.yaml
d8: web
${HOME}/src/v8/v8/out/x64.release/d8 out/web/ueforth.js
# ---- INSTALL ----
install: $(POSIX)/ueforth
sudo cp $< /usr/bin/ueforth
win-install: $(WINDOWS)/uEf32.exe $(WINDOWS)/uEf64.exe
cp $^ ~/Desktop/

View File

@ -4,14 +4,60 @@ This EForth inspired implementation of Forth is bootstraped from a minimalist C
## Building from Source
To build:
To build from source:
```
make
sudo apt install ninja-build gcc-arm-none-eabi
git clone https://github.com/flagxor/ueforth
cd ueforth
./configure.py
ninja
```
The resulting output will have this structure:
* out/deploy - A copy of the eforth.appspot.com / esp32forth.appspot.com ready to deploy.
* out/esp32 - A source build for ESP32.
* out/esp32-sim - A POSIX build approximating ESP32 for testing.
* out/pico-ice - A build for pico-ice.
* out/pico-ice-sim - A POSIX build approximating pico-ice for testing.
* out/gen - Intermediate / generated files.
* out/posix - A build for Linux / POSIX.
* out/resources - Intermediate / generated resources.
* out/web - A build for Web.
* out/windows - A build for Windows.
* out/linux - A build for Linux.
Individual platforms can be built as follows:
```
ninja posix
ninja esp32
ninja pico-ice
ninja win32
ninja win64
ninja web
```
A build that excludes the slower components can be configured with:
```
./configure.py -f
```
To install to /usr/bin on Linux / POSIX do:
```
ninja install
```
ESP32 boards can be compiled and flashed with:
```
ninja esp32-flash
ninja esp32s2-flash
ninja esp32s3-flash
ninja esp32c3-flash
ninja esp32cam-flash
```
Set PORT=com3 etc. to select board.

View File

@ -8,11 +8,11 @@
\
\ http://www.apache.org/licenses/LICENSE-2.0
\
\ Unless required by applicable law or agreed to in writing, software
\ distributed under the License is distributed on an "AS IS" BASIS,
\ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
\ See the License for the specific language governing permissions and
\ limitations under the License.
\ Unless required by applicable law or agreed to in writing, software
\ distributed under the License is distributed on an "AS IS" BASIS,
\ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
\ See the License for the specific language governing permissions and
\ limitations under the License.
( CircleForth )
vocabulary circleforth circleforth definitions

View File

@ -8,11 +8,11 @@
\
\ http://www.apache.org/licenses/LICENSE-2.0
\
\ Unless required by applicable law or agreed to in writing, software
\ distributed under the License is distributed on an "AS IS" BASIS,
\ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
\ See the License for the specific language governing permissions and
\ limitations under the License.
\ Unless required by applicable law or agreed to in writing, software
\ distributed under the License is distributed on an "AS IS" BASIS,
\ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
\ See the License for the specific language governing permissions and
\ limitations under the License.
( Useful basic compound words )
: 2drop ( n n -- ) drop drop ;

5
attic/oofda/README.md Normal file
View File

@ -0,0 +1,5 @@
# Oofda & Poke
An experimental Object system and Dependency injection framework for uEforth.
Vaguely inspired by Dagger, includes the CoffeeMaker example.

View File

@ -0,0 +1,99 @@
#! /usr/bin/env ueforth
\ Copyright 2023 Bradley D. Nelson
\
\ Licensed under the Apache License, Version 2.0 (the "License");
\ you may not use this file except in compliance with the License.
\ You may obtain a copy of the License at
\
\ http://www.apache.org/licenses/LICENSE-2.0
\
\ Unless required by applicable law or agreed to in writing, software
\ distributed under the License is distributed on an "AS IS" BASIS,
\ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
\ See the License for the specific language governing permissions and
\ limitations under the License.
needs ../poke.fs
needs ../lib/array.fs
needs ../lib/string.fs
( A logger to log steps while brewing coffee. )
class CoffeeLogger
value logs
: .construct 30 Array .new to logs ;
: .log ( a n -- ) String .new logs .append ;
: .dump logs .length 0 ?do
i logs .get .get type cr
loop cr ;
end-class
class LoggerModule
: .provideCoffeeLogger @Singleton CoffeeLogger .new ;
end-class
( A coffee maker to brew the coffee. )
class CoffeeMaker
value logger
value heater
value pump
m: .provideCoffeeLogger
m: .provideHeater m: .providePump
m: .on m: .off m: .pump m: .isHot?
: .construct @Inject CoffeeLogger to logger
@Inject Heater to heater
@Inject Pump to pump ;
: .brew heater .on
pump .pump
s" [_]P coffee! [_]P " logger .log
heater .off ;
end-class
class CoffeeMakerModule
: .provideCoffeeMaker CoffeeMaker .new ;
end-class
( An electric heater to heat the coffee. )
class ElectricHeater
value logger
value heating
: .construct @Inject CoffeeLogger to logger
0 to heating ;
: .on -1 to heating
s" ~ ~ ~ heating ~ ~ ~" logger .log ;
: .off 0 to heating ;
: .isHot? ( -- f ) heating ;
end-class
( A thermosiphon to pump the coffee. )
class Thermosiphon
value logger
value heater
: .construct @Inject CoffeeLogger to logger
@Inject Heater to heater ;
: .pump heater .isHot? if
s" => => pumping => =>" logger .log
then ;
end-class
class HeaterModule
: .provideHeater @Singleton ElectricHeater .new ;
end-class
class PumpModule
: .providePump Thermosiphon .new ;
end-class
( The main app responsible for brewing the coffee and printing the logs. )
class CoffeeApp extends Component
: .construct super .construct
HeaterModule this .include
PumpModule this .include
LoggerModule this .include
CoffeeMakerModule this .include ;
end-class
CoffeeApp .new constant coffeeShop
coffeeShop .provideCoffeeMaker .brew
coffeeShop .provideCoffeeLogger .dump
bye

View File

@ -0,0 +1,43 @@
#! /usr/bin/env ueforth
\ Copyright 2023 Bradley D. Nelson
\
\ Licensed under the Apache License, Version 2.0 (the "License");
\ you may not use this file except in compliance with the License.
\ You may obtain a copy of the License at
\
\ http://www.apache.org/licenses/LICENSE-2.0
\
\ Unless required by applicable law or agreed to in writing, software
\ distributed under the License is distributed on an "AS IS" BASIS,
\ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
\ See the License for the specific language governing permissions and
\ limitations under the License.
DEFER log
DEFER heater-on
DEFER heater-off
DEFER pump
: brew heater-on
pump
s" [_]P coffee! [_]P " log
heater-off ;
: console-log ( a n -- ) type cr ;
' console-log IS log
DEFER hot?
: thermosiphon
hot? if s" => => pumping => =>" log then ;
' thermosiphon IS pump
0 value switch
: electric-on -1 TO switch
s" ~ ~ ~ heating ~ ~ ~" log ;
: electric-off 0 TO switch ;
' electric-on IS heater-on
' electric-off IS heater-off
' switch IS hot?
brew
bye

31
attic/oofda/lib/array.fs Normal file
View File

@ -0,0 +1,31 @@
\ Copyright 2023 Bradley D. Nelson
\
\ Licensed under the Apache License, Version 2.0 (the "License");
\ you may not use this file except in compliance with the License.
\ You may obtain a copy of the License at
\
\ http://www.apache.org/licenses/LICENSE-2.0
\
\ Unless required by applicable law or agreed to in writing, software
\ distributed under the License is distributed on an "AS IS" BASIS,
\ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
\ See the License for the specific language governing permissions and
\ limitations under the License.
needs ../oofda.fs
class Array
value data
value length
value capacity
: .construct ( n -- ) to capacity
here to data capacity cells allot
0 to length ;
: .get ( n -- n ) cells data + @ ;
: .set ( n n -- ) cells data + ! ;
: .length ( -- n ) length ;
: .capacity ( -- n ) capacity ;
: .append ( n -- ) this .length this .capacity >= throw
this .length this .set 1 +to length ;
: .length ( -- n ) length ;
end-class

View File

@ -0,0 +1,37 @@
\ Copyright 2023 Bradley D. Nelson
\
\ Licensed under the Apache License, Version 2.0 (the "License");
\ you may not use this file except in compliance with the License.
\ You may obtain a copy of the License at
\
\ http://www.apache.org/licenses/LICENSE-2.0
\
\ Unless required by applicable law or agreed to in writing, software
\ distributed under the License is distributed on an "AS IS" BASIS,
\ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
\ See the License for the specific language governing permissions and
\ limitations under the License.
needs ../oofda.fs
class Logger
m: .logString
: .cr nl >r rp@ 1 this .logString rdrop ;
: .logNumber ( n -- ) <# #s #> this .logString ;
: .log ( a n -- ) this .logString this .cr ;
end-class
class NullLogger extends Logger
: .logString ( a n -- ) 2drop ;
end-class
class ConsoleLogger extends Logger
: .logString ( a n -- ) type ;
end-class
class FileLogger extends Logger
value handle
: .construct ( a n -- ) w/o create-file throw to handle ;
: .logString ( a n -- ) handle write-file drop ;
: .close handle close-file throw ;
end-class

View File

@ -1,4 +1,4 @@
\ Copyright 2021 Bradley D. Nelson
\ Copyright 2023 Bradley D. Nelson
\
\ Licensed under the Apache License, Version 2.0 (the "License");
\ you may not use this file except in compliance with the License.
@ -12,18 +12,17 @@
\ See the License for the specific language governing permissions and
\ limitations under the License.
( Lazy loaded Bluetooth Serial Terminal )
: bterm r|
vocabulary bterm bterm definitions
also bluetooth also internals
SerialBT.new constant bt
z" forth" 0 bt SerialBT.begin drop
esp_bt_dev_get_address hex 6 dump cr
: bt-type bt SerialBT.write drop ;
: bt-key
begin bt SerialBT.available until 0 >r rp@ 1 bt SerialBT.readBytes drop r> ;
: bt-on ['] bt-type is type ['] bt-key is key ;
: bt-off ['] serial-type is type ['] serial-key is key ;
only forth definitions
bterm 500 ms bt-on
| evaluate ;
needs stack.fs
class Queue
value stack1
value stack2
: .construct ( n -- ) dup Stack .new to stack1
Stack .new to stack2 ;
: .push ( n -- ) stack1 .push ;
: .transfer begin stack1 .empty? 0=
while stack1 .pop stack2 .push repeat ;
: .pop ( -- n ) stack2 .empty? if this .transfer then
stack2 .pop ;
: .empty? ( -- f ) stack1 .empty? stack2 .empty? and ;
end-class

25
attic/oofda/lib/stack.fs Normal file
View File

@ -0,0 +1,25 @@
\ Copyright 2023 Bradley D. Nelson
\
\ Licensed under the Apache License, Version 2.0 (the "License");
\ you may not use this file except in compliance with the License.
\ You may obtain a copy of the License at
\
\ http://www.apache.org/licenses/LICENSE-2.0
\
\ Unless required by applicable law or agreed to in writing, software
\ distributed under the License is distributed on an "AS IS" BASIS,
\ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
\ See the License for the specific language governing permissions and
\ limitations under the License.
needs ../oofda.fs
class Stack
variable start
variable sp
: .construct ( n -- ) here start ! here sp ! cells allot ;
: .empty? ( -- f ) sp @ start @ = ;
: .push ( n -- ) sp @ ! cell sp +! ;
: .pop ( -- n ) this .empty? throw
cell negate sp +! sp @ @ ;
end-class

25
attic/oofda/lib/string.fs Normal file
View File

@ -0,0 +1,25 @@
\ Copyright 2023 Bradley D. Nelson
\
\ Licensed under the Apache License, Version 2.0 (the "License");
\ you may not use this file except in compliance with the License.
\ You may obtain a copy of the License at
\
\ http://www.apache.org/licenses/LICENSE-2.0
\
\ Unless required by applicable law or agreed to in writing, software
\ distributed under the License is distributed on an "AS IS" BASIS,
\ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
\ See the License for the specific language governing permissions and
\ limitations under the License.
needs ../oofda.fs
class String
value length
value data
: .construct ( a n -- ) dup to length
here to data
here swap cmove
length allot ;
: .get ( -- a n ) data length ;
end-class

107
attic/oofda/oofda.fs Normal file
View File

@ -0,0 +1,107 @@
\ Copyright 2023 Bradley D. Nelson
\
\ Licensed under the Apache License, Version 2.0 (the "License");
\ you may not use this file except in compliance with the License.
\ You may obtain a copy of the License at
\
\ http://www.apache.org/licenses/LICENSE-2.0
\
\ Unless required by applicable law or agreed to in writing, software
\ distributed under the License is distributed on an "AS IS" BASIS,
\ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
\ See the License for the specific language governing permissions and
\ limitations under the License.
defined? oofda-max-methods 0= [IF]
100 constant oofda-max-methods
[THEN]
vocabulary classing also classing definitions also forth
variable 'this : this ( -- o ) 'this @ ;
variable methods variable last-method
: new-method ( ".name" -- xt )
methods @ oofda-max-methods >= throw
create methods @ , 1 methods +! latestxt
does> this >r swap ( save this ) 'this ! ( switch it )
dup last-method ! ( save last method )
@ cells this @ + @ execute ( invoke method )
r> 'this ! ( restore this ) ;
: method ( ".name" -- xt )
current @ >r also forth definitions
>in @ bl parse find dup if
nip
else
drop >in ! new-method
then
previous r> current ! ;
: m# ( "name" -- n ) method >body @ ;
: m: ( "name" ) method drop ; m: .construct ( make this 0 )
: m! ( xt n class ) swap 3 + cells + ! ;
m: .fallback
: undefined last-method @ 2 cells - ( body> ) this .fallback ;
: error-fallback ( xt -- ) ." Undefined method: " >name type cr throw -1 ;
: blank-vtable oofda-max-methods 0 do ['] undefined , loop ;
create ClassClass
here 3 cells + , ( vtable* )
0 , ( parent )
oofda-max-methods 3 + cells , ( size )
blank-vtable ( vtable[] )
: nop-construct ;
m: .size m: .grow m: .vtable m: .parent m: .getClass
:noname ( xt n ) this m! ; m# .setMethod ClassClass m!
: create ( "name" ) create this .size , does> @ this + ;
: variable ( "name" ) create this .size , cell this .grow does> @ this + ;
: value ( "name" ) create this .size , cell this .grow does> @ this + @ ;
: field' ( "name" -- n ) ' >body @ ;
: to ( n -- "name" ) field' postpone literal postpone this postpone +
postpone ! ; immediate
: +to ( n -- "name" ) field' postpone literal postpone this postpone +
postpone +! ; immediate
: dosuper ( n -- ) this ClassClass .getClass .parent .vtable + @ execute ;
: super ( "method" ) field' cells postpone literal postpone dosuper ; immediate
: : ( "name" ) m# :noname ;
: ; postpone ; swap this .setMethod ; immediate
: defining ( cls -- ) 'this ! current @ also classing definitions ;
definitions
m: .new m: .inherit
: class create ClassClass .new defining ;
: end-class previous current ! 0 'this ! ;
: extends ' execute this .inherit ;
: extend ' execute defining ;
: ClassClass ( -- cls ) ClassClass ;
previous previous definitions
extend ClassClass
: .parent ( -- a ) this cell+ @ ;
: .setParent ( a -- ) this cell+ ! ;
: .size& ( -- a ) this 2 cells + ;
: .size ( -- n ) this .size& @ ;
: .setSize ( -- n ) this .size& ! ;
: .grow ( n -- ) this .size + this .setSize ;
: .vtable ( -- a ) this 3 cells + ;
: .getClass ( o -- cls ) @ 3 cells - ;
: .allocate ( n -- a ) here swap allot ;
: .getName ( -- a n ) this 2 cells - >name ;
: .getMethod ( n -- xt ) cells this .vtable + @ ;
: .construct 0 this .setParent
cell this .setSize
oofda-max-methods 0 do ['] undefined i this .setMethod loop
['] error-fallback [ m# .fallback ] literal this .setMethod
['] nop-construct [ m# .construct ] literal this .setMethod ;
: .setup ( -- cls ) this .size this .allocate
dup this .size 0 fill
this .vtable over ! ;
: .new ( -- cls ) this .setup
dup >r .construct r> ;
: .inherit ( cls -- ) dup this .setParent
.size& this .size& oofda-max-methods 1+ cells cmove ;
end-class

59
attic/oofda/poke.fs Normal file
View File

@ -0,0 +1,59 @@
\ Copyright 2023 Bradley D. Nelson
\
\ Licensed under the Apache License, Version 2.0 (the "License");
\ you may not use this file except in compliance with the License.
\ You may obtain a copy of the License at
\
\ http://www.apache.org/licenses/LICENSE-2.0
\
\ Unless required by applicable law or agreed to in writing, software
\ distributed under the License is distributed on an "AS IS" BASIS,
\ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
\ See the License for the specific language governing permissions and
\ limitations under the License.
needs oofda.fs
needs lib/array.fs
also classing definitions also forth
variable provider
: do@Inject ( xt -- o ) provider @ swap execute ;
create name-buffer 200 allot 0 value name-length
: 0name 0 to name-length ;
: +name ( a n -- ) dup >r name-buffer name-length + swap cmove
r> +to name-length ;
: name ( -- a n ) name-buffer name-length ;
: @Inject ( "name" -- o ) 0name s" [ ' .provide" +name bl parse +name s" ]" +name
name evaluate postpone literal postpone do@Inject ; immediate
: do@Singleton ( n -- n ) this + dup @ if @ rdrop exit then
r> swap [ here 7 cells + ] literal swap >r >r >r exit
r> over >r ! r> ;
: @Singleton this .size postpone literal
cell this .grow
postpone do@Singleton ; immediate
previous previous definitions
class Component
value providers
: .construct 50 Array .new to providers ;
: .include ( m -- ) .new providers .append ;
: .hasMethod ( m n -- f )
providers .get ClassClass .getClass .getMethod ['] undefined <> ;
: .countHasMethod { m -- f }
0 providers .length 0 do
m i this .hasMethod if 1+ then
loop ;
: .pickHasMethod { m -- provider }
0 providers .length 0 do
m i this .hasMethod if i providers .get unloop exit then
loop -1 throw ;
: .fallback { xt } xt >body @ { m }
provider @ { old } this provider !
m this .countHasMethod { matches }
matches 1 > if ." Multiple Providers: " xt >name type cr -1 throw then
matches 1 <> if xt error-fallback then
m this .pickHasMethod xt execute
old provider ! ;
end-class

26
attic/oofda/run_tests.sh Normal file
View File

@ -0,0 +1,26 @@
#! /bin/bash
# Copyright 2023 Bradley D. Nelson
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
set -e
./tests/test1.fs
./tests/test2.fs
./tests/test3.fs
./tests/test4.fs
./tests/test5.fs
./tests/test6.fs
./tests/test7.fs
./examples/coffee.fs
./examples/simple_coffee.fs

View File

@ -0,0 +1,44 @@
#! /usr/bin/env ueforth
\ Copyright 2023 Bradley D. Nelson
\
\ Licensed under the Apache License, Version 2.0 (the "License");
\ you may not use this file except in compliance with the License.
\ You may obtain a copy of the License at
\
\ http://www.apache.org/licenses/LICENSE-2.0
\
\ Unless required by applicable law or agreed to in writing, software
\ distributed under the License is distributed on an "AS IS" BASIS,
\ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
\ See the License for the specific language governing permissions and
\ limitations under the License.
." test1.fs" cr
needs ../oofda.fs
class Foo
variable x
variable y
: .setX x ! ;
: .setY y ! ;
: .getX x @ ;
: .getY y @ ;
: .length2 this .getX dup * this .getY dup * + ;
: .construct 0 x ! 0 y ! ;
: .print ." x: " this .getX . ." y: " this .getY . cr ;
end-class
Foo .new .print
class Bar extends Foo
: .dude this .print this .print ;
end-class
Foo .new .print
Bar .new constant h
h .dude
123 h .setX 456 h .setY
h .dude
bye

View File

@ -0,0 +1,38 @@
#! /usr/bin/env ueforth
\ Copyright 2023 Bradley D. Nelson
\
\ Licensed under the Apache License, Version 2.0 (the "License");
\ you may not use this file except in compliance with the License.
\ You may obtain a copy of the License at
\
\ http://www.apache.org/licenses/LICENSE-2.0
\
\ Unless required by applicable law or agreed to in writing, software
\ distributed under the License is distributed on an "AS IS" BASIS,
\ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
\ See the License for the specific language governing permissions and
\ limitations under the License.
." test2.fs" cr
needs ../oofda.fs
class Foo
variable x
variable y
: .setX x ! ;
: .setY y ! ;
: .getX x @ ;
: .getY y @ ;
: .length2 this .getX dup * this .getY dup * + ;
: .print ." x: " this .getX . ." y: " this .getY . cr ;
end-class
class Bar extends Foo
: .dude this .print this .print ;
end-class
Bar .new constant h
123 h .setX 456 h .setY
h .dude
bye

View File

@ -0,0 +1,58 @@
#! /usr/bin/env ueforth
\ Copyright 2023 Bradley D. Nelson
\
\ Licensed under the Apache License, Version 2.0 (the "License");
\ you may not use this file except in compliance with the License.
\ You may obtain a copy of the License at
\
\ http://www.apache.org/licenses/LICENSE-2.0
\
\ Unless required by applicable law or agreed to in writing, software
\ distributed under the License is distributed on an "AS IS" BASIS,
\ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
\ See the License for the specific language governing permissions and
\ limitations under the License.
." test3.fs" cr
needs ../oofda.fs
class Pair
variable first
variable second
: .construct ( x y -- ) second ! first ! ;
: .unpair first @ second @ ;
end-class
class Coolness extends Pair
variable third
: .construct ( x y z -- ) super .construct third ! ;
: .unpair super .unpair third @ ;
end-class
123 456 Pair .new constant h
h .unpair . . cr
123 456 789 Coolness .new constant h2
h2 .unpair . . . cr
class Stack
variable sp
create start
100 cells this .grow
: .construct start sp ! ;
: .empty? ( -- f ) sp @ start @ = ;
: .push ( n -- ) sp @ ! cell sp +! ;
: .pop ( -- n ) this .empty? throw
cell negate sp +! sp @ @ ;
end-class
100 Stack .new constant s
123 s .push
234 s .push
345 s .push
s .pop . cr
s .pop . cr
s .pop . cr
bye

View File

@ -0,0 +1,39 @@
#! /usr/bin/env ueforth
\ Copyright 2023 Bradley D. Nelson
\
\ Licensed under the Apache License, Version 2.0 (the "License");
\ you may not use this file except in compliance with the License.
\ You may obtain a copy of the License at
\
\ http://www.apache.org/licenses/LICENSE-2.0
\
\ Unless required by applicable law or agreed to in writing, software
\ distributed under the License is distributed on an "AS IS" BASIS,
\ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
\ See the License for the specific language governing permissions and
\ limitations under the License.
." test4.fs" cr
needs ../lib/stack.fs
needs ../lib/queue.fs
100 Stack .new constant s
123 s .push
234 s .push
345 s .push
s .pop . cr
s .pop . cr
s .pop . cr
100 Queue .new constant q
123 q .push
234 q .push
q .pop . cr
345 q .push
q .pop . cr
456 q .push
q .pop . cr
q .pop . cr
bye

View File

@ -0,0 +1,39 @@
#! /usr/bin/env ueforth
\ Copyright 2023 Bradley D. Nelson
\
\ Licensed under the Apache License, Version 2.0 (the "License");
\ you may not use this file except in compliance with the License.
\ You may obtain a copy of the License at
\
\ http://www.apache.org/licenses/LICENSE-2.0
\
\ Unless required by applicable law or agreed to in writing, software
\ distributed under the License is distributed on an "AS IS" BASIS,
\ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
\ See the License for the specific language governing permissions and
\ limitations under the License.
." test5.fs" cr
needs ../lib/logging.fs
: @Inject ( "name" -- x )
bl parse
2dup s" Range" str= if 2drop 10 postpone literal exit then
2dup s" Logger" str= if 2drop postpone ConsoleLogger postpone .new exit then
-1 throw
; immediate
class Counter
value log
value range
: .construct @Inject Range to range
@Inject Logger to log ;
: .doit ( n -- ) s" Counter at: " log .logString log
.logNumber log .cr ;
: .run range 0 do i 1+ this .doit loop ;
end-class
Counter .new .run
bye

View File

@ -0,0 +1,28 @@
#! /usr/bin/env ueforth
\ Copyright 2023 Bradley D. Nelson
\
\ Licensed under the Apache License, Version 2.0 (the "License");
\ you may not use this file except in compliance with the License.
\ You may obtain a copy of the License at
\
\ http://www.apache.org/licenses/LICENSE-2.0
\
\ Unless required by applicable law or agreed to in writing, software
\ distributed under the License is distributed on an "AS IS" BASIS,
\ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
\ See the License for the specific language governing permissions and
\ limitations under the License.
." test6.fs" cr
needs ../lib/array.fs
10 Array .new constant a
1 a .append
2 a .append
3 a .append
1 a .get . cr
bye

View File

@ -0,0 +1,55 @@
#! /usr/bin/env ueforth
\ Copyright 2023 Bradley D. Nelson
\
\ Licensed under the Apache License, Version 2.0 (the "License");
\ you may not use this file except in compliance with the License.
\ You may obtain a copy of the License at
\
\ http://www.apache.org/licenses/LICENSE-2.0
\
\ Unless required by applicable law or agreed to in writing, software
\ distributed under the License is distributed on an "AS IS" BASIS,
\ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
\ See the License for the specific language governing permissions and
\ limitations under the License.
." test7.fs" cr
needs ../poke.fs
needs ../lib/logging.fs
class Counter
value log
value range
m: .provideRange
m: .provideLogger
m: .logString
m: .logNumber
m: .cr
: .construct @Inject Range to range
@Inject Logger to log ;
: .doit ( n -- ) s" Counter at: " log .logString
log .logNumber log .cr ;
: .run range 0 do i 1+ this .doit loop ;
end-class
class CountingModule
: .provideCounter @Singleton Counter .new ;
: .provideRange 10 ;
end-class
class LoggingModule
\ : .provideLogFilename s" log.txt" ;
\ : .provideLogger @Singleton @Inject LogFilename FileLogger .new ;
: .provideLogger @Singleton ConsoleLogger .new ;
end-class
class ProgramComponent extends Component
: .construct super .construct
LoggingModule this .include
CountingModule this .include ;
end-class
ProgramComponent .new .provideCounter .run
bye

View File

@ -16,13 +16,17 @@ needs testing.fs
needs utils.fs
needs base_tests.fs
needs utils_tests.fs
needs throw_values_tests.fs
needs vocabulary_tests.fs
needs locals_tests.fs
needs case_tests.fs
needs doloop_tests.fs
needs conditionals_tests.fs
needs float_tests.fs
needs recognizer_tests.fs
needs forth_namespace_tests.fs
needs structures_tests.fs
needs fault_tests.fs
needs including_tests/including_tests.fs
needs modules_tests.fs
needs ../lib/hashing/sha1_tests.fs

54
common/altcase.fs Normal file
View File

@ -0,0 +1,54 @@
\ Copyright 2022 Bradley D. Nelson
\
\ Licensed under the Apache License, Version 2.0 (the "License");
\ you may not use this file except in compliance with the License.
\ You may obtain a copy of the License at
\
\ http://www.apache.org/licenses/LICENSE-2.0
\
\ Unless required by applicable law or agreed to in writing, software
\ distributed under the License is distributed on an "AS IS" BASIS,
\ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
\ See the License for the specific language governing permissions and
\ limitations under the License.
( A WIP exploration of an optimized version of CASE. )
( NOTE: NOT YET FUNCTIONAL )
( TODO: complete this )
internals definitions
create case-buffer 400 cells allot
variable cases
variable default-target variable default-fixup
: case, ( n -- ) case-buffer cases @ cells + ! 1 cases +! ;
forth definitions internals
( default num target fixup )
: CASE ( n -- )
0 cases ! 0 default-target ! 0 default-fixup !
postpone ahead postpone [ ; immediate
: ENDCASE postpone ] postpone then
case-buffer cases @ 3 / for aft
dup @ . cell+
dup @ . cell+
dup @ . cell+ cr
then next drop ; immediate
: OTHERWISE here default-target ! postpone ] ; immediate
: OF ( n -- ) case, here case, postpone ] ; immediate
: ENDOF postpone [ postpone ahead
default-target @ default-fixup @ 0= and
if default-fixup ! else case, then ; immediate
forth definitions
: test
case
1 of ." one" endof
2 of ." two" endof
3 of ." three" endof
otherwise ." other" endof
endcase
;
see test

128
common/assembler.fs Normal file
View File

@ -0,0 +1,128 @@
\ Copyright 2022 Bradley D. Nelson
\
\ Licensed under the Apache License, Version 2.0 (the "License");
\ you may not use this file except in compliance with the License.
\ You may obtain a copy of the License at
\
\ http://www.apache.org/licenses/LICENSE-2.0
\
\ Unless required by applicable law or agreed to in writing, software
\ distributed under the License is distributed on an "AS IS" BASIS,
\ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
\ See the License for the specific language governing permissions and
\ limitations under the License.
( Lazy loaded assembler/disassembler framework )
: assembler r|
current @
also internals
also asm definitions
-1 1 rshift invert constant high-bit
: odd? ( n -- f ) 1 and ;
: >>1 ( n -- n ) 1 rshift ;
: enmask ( n m -- n )
0 -rot cell 8 * 1- for
rot >>1 -rot
dup odd? if
over odd? if rot high-bit or -rot then
swap >>1 swap
then
>>1
next
2drop
;
: demask ( n m -- n )
0 >r begin dup while
dup 0< if over 0< if r> 2* 1+ >r else r> 2* >r then then
2* swap 2* swap
repeat 2drop r>
;
variable length variable pattern variable mask
: bit! ( n a -- ) dup @ 2* rot 1 and or swap ! ;
: >opmask& ( xt -- a ) >body ;
: >next ( xt -- xt ) >body cell+ @ ;
: >inop ( a -- a ) >body 2 cells + @ ;
: >printop ( a -- a ) >body 3 cells + @ ;
variable operands
: for-operands ( xt -- )
>r operands @ begin dup while r> 2dup >r >r execute r> >next repeat rdrop drop ;
: reset-operand ( xt -- ) >opmask& 0 swap ! ;
: reset 0 length ! 0 mask ! 0 pattern ! ['] reset-operand for-operands ;
: advance-operand ( xt -- ) >opmask& 0 swap bit! ;
: advance ['] advance-operand for-operands ;
: skip 1 length +! 0 mask bit! 0 pattern bit! advance ;
: bit ( n -- ) 1 length +! 1 mask bit! pattern bit! advance ;
: bits ( val n ) 1- for dup r@ rshift bit next drop ;
: o 0 bit ; : l 1 bit ;
( struct: pattern next inop printop )
: operand ( inop printop "name" )
create 0 , operands @ , latestxt operands ! swap , ,
does> skip 1 swap +! ;
: names ( n "names"*n --) 0 swap 1- for dup constant 1+ next drop ;
: coden, ( val n -- ) 8 / 1- for dup code1, 8 rshift next drop ;
( struct: length pattern mask [xt pattern]* 0 )
variable opcodes
: op-snap ( xt -- ) dup >opmask& @ if dup , >opmask& @ , else drop then ;
: >xt ( a -- xt ) 2 cells - ;
: >length ( xt -- a ) >body cell+ @ ;
: >pattern ( xt -- a ) >body 2 cells + @ ;
: >mask ( xt -- a ) >body 3 cells + @ ;
: >operands ( xt -- a ) >body 4 cells + ;
: op ( "name" )
create opcodes @ , latestxt opcodes !
length @ , pattern @ , mask @ ,
['] op-snap for-operands 0 , reset
does> >xt >r
r@ >pattern
0 r@ >operands begin dup @ while >r 1+ r> 2 cells + repeat
swap for aft
2 cells - dup >r swap >r dup cell+ @ >r @ >inop execute r> enmask r> or r>
then next
drop
r> >length coden,
;
: for-ops ( xt -- )
>r opcodes @ begin dup while r> 2dup >r >r execute r> >body @ repeat rdrop drop ;
: m@ ( a -- n ) 0 swap cell 0 do dup ca@ i 8 * lshift swap >r or r> 1+ loop drop ;
: m. ( n n -- ) base @ hex >r >r <# r> 1- for # # next #> type r> base ! ;
: sextend ( n n -- n ) cell 8 * swap - dup >r lshift r> arshift ;
variable istep
variable address
: matchit ( a xt -- a )
>r dup m@ r@ >mask and r@ >pattern = if
r@ >operands begin dup @ while
>r dup m@ r@ cell+ @ demask r@ @ >printop execute r> 2 cells +
repeat drop
r@ see.
r@ >length 8 / istep !
then rdrop ;
: disasm1 ( a -- a )
dup address ! dup . ." -- " 0 istep ! ['] matchit for-ops
istep @ 0= if 1 istep ! ." UNKNOWN!!!" then
9 emit 9 emit ." -- " dup m@ istep @ m.
istep @ +
cr
;
: disasm ( a n -- ) for aft disasm1 then next drop ;
previous previous
also forth definitions
: assembler asm ;
previous
assembler
current !
| evaluate ;

View File

@ -157,3 +157,81 @@ e: test-2@2!
123 =assert
999 =assert
;e
e: test-/
101 2 / 50 =assert
101 -2 / -51 =assert
-101 -2 / 50 =assert
-101 2 / -51 =assert
100 2 / 50 = assert
100 -2 / -50 = assert
-100 -2 / 50 = assert
-100 2 / -50 = assert
;e
e: test-mod
101 2 mod 1 =assert
101 -2 mod -1 =assert
-101 -2 mod -1 =assert
-101 2 mod 1 =assert
100 2 mod 0 =assert
100 -2 mod 0 =assert
-100 -2 mod 0 =assert
-100 2 mod 0 =assert
;e
e: test-/mod-consistent
101 2 /mod 50 =assert 1 =assert
101 -2 /mod -51 =assert -1 =assert
-101 -2 /mod 50 =assert -1 =assert
-101 2 /mod -51 =assert 1 =assert
100 2 /mod 50 = assert 0 =assert
100 -2 /mod -50 = assert 0 =assert
-100 -2 /mod 50 = assert 0 =assert
-100 2 /mod -50 = assert 0 =assert
;e
e: test-/mod-consistent
: /mod-check { a b -- } a b /mod b * + a = assert ;
101 2 /mod-check
101 -2 /mod-check
-101 2 /mod-check
-101 -2 /mod-check
100 2 /mod-check
100 -2 /mod-check
-100 2 /mod-check
-100 -2 /mod-check
;e
e: test-*/
50 2 4 */ 25 =assert
-50 2 4 */ -25 =assert
;e
e: test-/cell
10 cells cell/ 10 =assert
10 cells 1+ cell/ 10 =assert
-10 cells cell/ -10 =assert
-10 cells 1- cell/ -11 =assert
;e
e: test-u<
1 3 u< assert
3 1 u< 0= assert
0 -1 u< assert
-1 0 u< 0= assert
0 0 u< 0= assert
-1 -1 u< 0= assert
;e
e: test-postpone
: test postpone if postpone + postpone then ; immediate
: test2 test ;
3 4 1 test2 . cr
3 4 0 test2 . . cr
out: 7
out: 4 3
;e

View File

@ -29,6 +29,7 @@ typedef struct {
int argc;
char **argv;
cell_t *(*runner)(cell_t *rp); // pointer to forth_run
cell_t **throw_handler;
// Layout not used by Forth.
cell_t *rp; // spot to park main thread
@ -36,3 +37,6 @@ typedef struct {
void *DOCREATE_OP;
const BUILTIN_WORD *builtins;
} G_SYS;
static G_SYS *g_sys = 0;
static cell_t *forth_run(cell_t *init_rp);

View File

@ -16,12 +16,6 @@
sp@ constant sp0
rp@ constant rp0
fp@ constant fp0
: depth ( -- n ) sp@ sp0 - cell/ ;
: fdepth ( -- n ) fp@ fp0 - 4 / ;
( Useful heap size words )
: remaining ( -- n ) 'heap-start @ 'heap-size @ + 'heap @ - ;
: used ( -- n ) 'heap @ sp@ 'stack-cells @ cells + - 28 + ;
( Quoting Words )
: ' bl parse 2dup find dup >r -rot r> 0= 'notfound @ execute 2drop ;
@ -44,9 +38,9 @@ create AFT ' branch @ ' aft ! : aft drop ['] aft , here 0 , here swap
( Recursion )
: recurse current @ @ aliteral ['] execute , ; immediate
( Postpone - done here so we have ['] and IF )
( Tools to build postpone later out of recognizers )
: immediate? ( xt -- f ) >flags 1 and 0= 0= ;
: postpone ' dup immediate? if , else aliteral ['] , , then ; immediate
: postpone, ( xt -- ) aliteral ['] , , ;
( Rstack nest depth )
variable nest-depth
@ -55,6 +49,67 @@ variable nest-depth
create FOR ' >r @ ' for ! : for 1 nest-depth +! ['] for , here ; immediate
create NEXT ' donext @ ' next ! : next -1 nest-depth +! ['] next , , ; immediate
( Define a data type for Recognizers. )
: RECTYPE: ( xt-interpret xt-compile xt-postpone "name" -- ) CREATE , , , ;
: do-notfound ( a n -- ) -1 'notfound @ execute ;
' do-notfound ' do-notfound ' do-notfound RECTYPE: RECTYPE-NONE
' execute ' , ' postpone, RECTYPE: RECTYPE-WORD
' execute ' execute ' , RECTYPE: RECTYPE-IMM
' drop ' execute ' execute RECTYPE: RECTYPE-NUM
: RECOGNIZE ( c-addr len addr1 -- i*x addr2 )
dup @ for aft
cell+ 3dup >r >r >r @ execute
dup RECTYPE-NONE <> if rdrop rdrop rdrop rdrop exit then
drop r> r> r>
then next
drop RECTYPE-NONE
;
( Define a recognizer stack. )
create RECSTACK 0 , bl 2/ ( 16 no numbers yet ) cells allot
: +RECOGNIZER ( xt -- ) 1 RECSTACK +! RECSTACK dup @ cells + ! ;
: -RECOGNIZER ( -- ) -1 RECSTACK +! ;
: GET-RECOGNIZERS ( -- xtn..xt1 n )
RECSTACK @ for RECSTACK r@ cells + @ next ;
: SET-RECOGNIZERS ( xtn..xt1 n -- )
0 RECSTACK ! for aft +RECOGNIZER then next ;
( Create recognizer based words. )
: postpone ( "name" -- ) bl parse RECSTACK RECOGNIZE @ execute ; immediate
: +evaluate1
bl parse dup 0= if 2drop exit then
RECSTACK RECOGNIZE state @ 1+ 1+ cells + @ execute
;
( Setup recognizing words. )
: REC-FIND ( c-addr len -- xt addr1 | addr2 )
find dup if
dup immediate? if RECTYPE-IMM else RECTYPE-WORD then
else
drop RECTYPE-NONE
then
;
' REC-FIND +RECOGNIZER
( Setup recognizing integers. )
: REC-NUM ( c-addr len -- n addr1 | addr2 )
s>number? if
['] aliteral RECTYPE-NUM
else
RECTYPE-NONE
then
;
' REC-NUM +RECOGNIZER
: interpret0 begin +evaluate1 again ; interpret0
( Useful stack/heap words )
: depth ( -- n ) sp@ sp0 - cell/ ;
: fdepth ( -- n ) fp@ fp0 - 4 / ;
: remaining ( -- n ) 'heap-start @ 'heap-size @ + 'heap @ - ;
: used ( -- n ) 'heap @ sp@ 'stack-cells @ cells + - 28 + ;
( DO..LOOP )
variable leaving
: leaving, here leaving @ , leaving ! ;
@ -69,10 +124,12 @@ variable leaving
: UNLOOP r> rdrop rdrop >r ;
: LEAVE r> rdrop rdrop @ >r ;
: leave postpone LEAVE leaving, ; immediate
: +LOOP ( n -- ) dup 0< swap r> r> rot + dup r@ < -rot >r >r xor 0=
: +LOOP ( n -- ) r> r> dup r@ - >r rot + r> -rot
dup r@ - -rot >r >r xor 0<
if r> cell+ rdrop rdrop >r else r> @ >r then ;
: +loop ( n -- ) postpone +LOOP , )leaving ; immediate
: LOOP r> r> 1+ dup r@ < -rot >r >r 0=
: LOOP r> r> dup r@ - >r 1+ r> -rot
dup r@ - -rot >r >r xor 0<
if r> cell+ rdrop rdrop >r else r> @ >r then ;
: loop postpone LOOP , )leaving ; immediate
create I ' r@ @ ' i ! ( i is same as r@ )
@ -81,6 +138,7 @@ create I ' r@ @ ' i ! ( i is same as r@ )
( Exceptions )
variable handler
handler 'throw-handler !
: catch ( xt -- n )
fp@ >r sp@ >r handler @ >r rp@ handler ! execute
r> handler ! rdrop rdrop 0 ;

View File

@ -25,6 +25,9 @@ typedef cell_t (CALLTYPE *call_t)();
#define ct0 ((call_t) n0)
#define CALLING_OPCODE_LIST \
YV(internals, CALLCODE, float *t_fp = fp; DUP; \
sp = (cell_t *) (*(call_t*) (w + sizeof(cell_t)))(sp, &t_fp); \
fp = t_fp; DROP) \
YV(internals, CALL0, n0 = ct0()) \
YV(internals, CALL1, n0 = ct0(n1); --sp) \
YV(internals, CALL2, n0 = ct0(n2, n1); sp -= 2) \

25
common/case.fs Normal file
View File

@ -0,0 +1,25 @@
\ Copyright 2022 Bradley D. Nelson
\
\ Licensed under the Apache License, Version 2.0 (the "License");
\ you may not use this file except in compliance with the License.
\ You may obtain a copy of the License at
\
\ http://www.apache.org/licenses/LICENSE-2.0
\
\ Unless required by applicable law or agreed to in writing, software
\ distributed under the License is distributed on an "AS IS" BASIS,
\ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
\ See the License for the specific language governing permissions and
\ limitations under the License.
internals definitions
variable cases
forth definitions internals
: CASE ( n -- ) cases @ 0 cases ! ; immediate
: ENDCASE postpone drop cases @ for aft postpone then then next
cases ! ; immediate
: OF ( n -- ) postpone over postpone = postpone if postpone drop ; immediate
: ENDOF 1 cases +! postpone else ; immediate
forth definitions

65
common/case_tests.fs Normal file
View File

@ -0,0 +1,65 @@
\ Copyright 2021 Bradley D. Nelson
\
\ Licensed under the Apache License, Version 2.0 (the "License");
\ you may not use this file except in compliance with the License.
\ You may obtain a copy of the License at
\
\ http://www.apache.org/licenses/LICENSE-2.0
\
\ Unless required by applicable law or agreed to in writing, software
\ distributed under the License is distributed on an "AS IS" BASIS,
\ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
\ See the License for the specific language governing permissions and
\ limitations under the License.
( Test CASE Works )
e: test-case
: foo
case
1 of ." one" cr endof
2 of ." two" cr endof
." other: " dup . cr
endcase
;
1 foo
out: one
2 foo
out: two
3 foo
out: other: 3
;e
e: test-case-dup
: foo
case
1 of ." one" cr endof
2 of ." two" cr endof
1 of ." onemore" cr endof
." other: " dup . cr
endcase
;
1 foo
out: one
2 foo
out: two
3 foo
out: other: 3
;e
e: test-case-string
: foo
case
1 of s" one" endof
2 of s" two" endof
1 of s" onemore" endof
>r s" other" r>
endcase
;
1 foo type cr
out: one
2 foo type cr
out: two
3 foo type cr
out: other
;e

69
common/code.fs Normal file
View File

@ -0,0 +1,69 @@
\ Copyright 2022 Bradley D. Nelson
\
\ Licensed under the Apache License, Version 2.0 (the "License");
\ you may not use this file except in compliance with the License.
\ You may obtain a copy of the License at
\
\ http://www.apache.org/licenses/LICENSE-2.0
\
\ Unless required by applicable law or agreed to in writing, software
\ distributed under the License is distributed on an "AS IS" BASIS,
\ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
\ See the License for the specific language governing permissions and
\ limitations under the License.
( Lazy loaded code words )
: asm r|
also forth definitions
vocabulary asm
internals definitions
: ca! ( n a -- ) dup cell-base >r cell-shift swap over lshift
swap 255 swap lshift invert r@ @ and or r> ! ;
also asm definitions
variable code-start
variable code-at
DEFINED? posix [IF]
also posix
: reserve ( n -- )
0 swap PROT_READ PROT_WRITE PROT_EXEC or or
MAP_ANONYMOUS MAP_PRIVATE or -1 0 mmap code-start ! ;
previous
4096 reserve
[THEN]
DEFINED? esp [IF]
also esp
: reserve ( n -- ) MALLOC_CAP_EXEC heap_caps_malloc code-start ! ;
previous
1024 reserve
[THEN]
code-start @ code-at !
: chere ( -- a ) code-at @ ;
: callot ( n -- ) code-at +! ;
: code1, ( n -- ) chere ca! 1 callot ;
: code2, ( n -- ) dup code1, 8 rshift code1, ;
: code3, ( n -- ) dup code2, 16 rshift code1, ;
: code4, ( n -- ) dup code2, 16 rshift code2, ;
cell 8 = [IF]
: code, dup code4, 32 rshift code4, ;
[ELSE]
: code, code4, ;
[THEN]
: end-code previous ;
also forth definitions
: code ( "name" ) create ['] callcode @ latestxt !
code-at @ latestxt cell+ ! also asm ;
previous previous previous
asm
| evaluate ;

View File

@ -12,7 +12,7 @@
\ See the License for the specific language governing permissions and
\ limitations under the License.
: ( 41 parse drop drop ; immediate
: \ 10 parse drop drop ; immediate
: #! 10 parse drop drop ; immediate ( shebang for scripts )
( Now can do comments! )
: ( bl nl + 1- parse drop drop ; immediate ( Now can do comments! )
( bl=32 nl=10 so nl+32-1=41, right paren )
: \ nl parse drop drop ; immediate
: #! nl parse drop drop ; immediate ( shebang for scripts )

View File

@ -15,9 +15,12 @@
( Interpret time conditionals )
: DEFINED? ( "name" -- xt|0 )
bl parse find state @ if aliteral then ; immediate
begin bl parse dup 0= while 2drop refill 0= throw repeat
find state @ if aliteral then ; immediate
defer [SKIP]
: [THEN] ; : [ELSE] [SKIP] ; : [IF] 0= if [SKIP] then ;
: [THEN] ; immediate
: [ELSE] [SKIP] ; immediate
: [IF] 0= if [SKIP] then ; immediate
: [SKIP]' 0 begin postpone defined? dup if
dup ['] [IF] = if swap 1+ swap then
dup ['] [ELSE] = if swap dup 0 <= if 2drop exit then swap then

View File

@ -43,8 +43,6 @@ enum {
#undef V
};
static G_SYS *g_sys = 0;
static cell_t convert(const char *pos, cell_t n, cell_t base, cell_t *ret) {
*ret = 0;
cell_t negate = 0;
@ -109,6 +107,9 @@ static cell_t same(const char *a, const char *b, cell_t len) {
}
static cell_t find(const char *name, cell_t len) {
if (len == 0) {
return 0;
}
for (cell_t ***voc = g_sys->context; *voc; ++voc) {
cell_t xt = (cell_t) **voc;
while (xt) {
@ -187,35 +188,12 @@ static cell_t *evaluate1(cell_t *rp) {
call = xt;
}
} else {
cell_t n;
if (convert((const char *) name, len, g_sys->base, &n)) {
if (g_sys->state) {
COMMA(g_sys->DOLIT_XT);
COMMA(n);
} else {
PUSH n;
}
} else {
float f;
if (fconvert((const char *) name, len, &f)) {
if (g_sys->state) {
COMMA(g_sys->DOFLIT_XT);
*(float *) g_sys->heap++ = f;
} else {
*++fp = f;
}
} else {
#if PRINT_ERRORS
fprintf(stderr, "CANT FIND: ");
fwrite((void *) name, 1, len, stderr);
fprintf(stderr, "\n");
fprintf(stderr, "CANT FIND: ");
fwrite((void *) name, 1, len, stderr);
fprintf(stderr, "\n");
#endif
PUSH name;
PUSH len;
PUSH -1;
call = g_sys->notfound;
}
}
return 0;
}
PUSH call;
PARK;
@ -282,9 +260,9 @@ static void forth_init(int argc, char *argv[],
g_sys->tib = src;
g_sys->ntib = src_len;
*++rp = (cell_t) start;
*++rp = (cell_t) fp;
*++rp = (cell_t) sp;
*++rp = (cell_t) start;
g_sys->rp = rp;
g_sys->runner = forth_run;
}

View File

@ -42,74 +42,74 @@ e: test-rev-?doloop
e: test-do+loop
: foo 0 do i . 2 +loop cr ;
9 foo
out: 0 2 4 6 8
10 foo
out: 0 2 4 6 8
11 foo
out: 0 2 4 6 8 10
1 foo
out: 0
." 9 foo " 9 foo
out: 9 foo 0 2 4 6 8
." 10 foo " 10 foo
out: 10 foo 0 2 4 6 8
." 11 foo " 11 foo
out: 11 foo 0 2 4 6 8 10
." 1 foo " 1 foo
out: 1 foo 0
;e
e: test-?do+loop
: foo 0 ?do i . 2 +loop cr ;
9 foo
out: 0 2 4 6 8
10 foo
out: 0 2 4 6 8
11 foo
out: 0 2 4 6 8 10
1 foo
out: 0
0 foo
out:
." 9 foo " 9 foo
out: 9 foo 0 2 4 6 8
." 10 foo " 10 foo
out: 10 foo 0 2 4 6 8
." 11 foo " 11 foo
out: 11 foo 0 2 4 6 8 10
." 1 foo " 1 foo
out: 1 foo 0
." 0 foo " 0 foo
out: 0 foo
;e
e: test-doloop-leave
: foo 0 do 42 emit i 7 = if ." left " leave ." nope" then i . loop cr ;
7 foo
out: *0 *1 *2 *3 *4 *5 *6
8 foo
out: *0 *1 *2 *3 *4 *5 *6 *left
9 foo
out: *0 *1 *2 *3 *4 *5 *6 *left
." 7 foo " 7 foo
out: 7 foo *0 *1 *2 *3 *4 *5 *6
." 8 foo " 8 foo
out: 8 foo *0 *1 *2 *3 *4 *5 *6 *left
." 9 foo " 9 foo
out: 9 foo *0 *1 *2 *3 *4 *5 *6 *left
;e
e: test-do+loop-leave
: foo 0 do 42 emit i 8 = if ." left " leave ." nope" then i . 2 +loop cr ;
7 foo
out: *0 *2 *4 *6
8 foo
out: *0 *2 *4 *6
9 foo
out: *0 *2 *4 *6 *left
0 foo
out: *0
." 7 foo " 7 foo
out: 7 foo *0 *2 *4 *6
." 8 foo " 8 foo
out: 8 foo *0 *2 *4 *6
." 9 foo " 9 foo
out: 9 foo *0 *2 *4 *6 *left
." 0 foo " 0 foo
out: 0 foo *0 *2 *4 *6 *left
;e
e: test-?do+loop-leave
: foo 0 ?do 42 emit i 8 = if ." left " leave ." nope" then i . 2 +loop cr ;
7 foo
out: *0 *2 *4 *6
8 foo
out: *0 *2 *4 *6
9 foo
out: *0 *2 *4 *6 *left
0 foo
out:
." 7 foo " 7 foo
out: 7 foo *0 *2 *4 *6
." 8 foo " 8 foo
out: 8 foo *0 *2 *4 *6
." 9 foo " 9 foo
out: 9 foo *0 *2 *4 *6 *left
." 0 foo " 0 foo
out: 0 foo
;e
e: test-do+loop-unloop
: foo 0 do 42 emit i 8 = if ." left " cr unloop exit then i . 2 +loop ." done " cr ;
7 foo
out: *0 *2 *4 *6 done
8 foo
out: *0 *2 *4 *6 done
9 foo
out: *0 *2 *4 *6 *left
0 foo
out: *0 done
." 7 foo " 7 foo
out: 7 foo *0 *2 *4 *6 done
." 8 foo " 8 foo
out: 8 foo *0 *2 *4 *6 done
." 9 foo " 9 foo
out: 9 foo *0 *2 *4 *6 *left
." 0 foo " 0 foo
out: 0 foo *0 *2 *4 *6 *left
;e
e: test-?do+loop-unloop
@ -130,3 +130,14 @@ e: test-doloop-j
out: 0 0 0 1 1 1 2 2 2 3 3 3 4 4 4
;e
e: test-doloop-unsigned
: foo 0 -1 1 rshift 1+ dup 10 + swap do 1+ loop . cr ;
foo
out: 10
;e
e: test-do+loop-unsigned
: foo 0 -1 1 rshift dup 10 + do 1+ -1 +loop . cr ;
foo
out: 11
;e

64
common/fault_tests.fs Normal file
View File

@ -0,0 +1,64 @@
\ Copyright 2022 Bradley D. Nelson
\
\ Licensed under the Apache License, Version 2.0 (the "License");
\ you may not use this file except in compliance with the License.
\ You may obtain a copy of the License at
\
\ http://www.apache.org/licenses/LICENSE-2.0
\
\ Unless required by applicable law or agreed to in writing, software
\ distributed under the License is distributed on an "AS IS" BASIS,
\ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
\ See the License for the specific language governing permissions and
\ limitations under the License.
( Testing Memory Faults )
( Skip on ESP32 as not emulated. )
DEFINED? esp 0= [IF]
e: test-read-null
0 ' @ catch assert drop
;e
e: test-read-1023
1023 ' @ catch assert drop
;e
e: test-read-1024
1024 ' @ catch assert drop
;e
e: test-write-null
123 0 ' ! catch assert 2drop
;e
e: test-write-1023
123 1023 ' ! catch assert 2drop
;e
e: test-write-1024
123 1024 ' ! catch assert 2drop
;e
( Skip on win64 because wine can't handle these, unsure why. )
DEFINED? windows 0= cell 4 = or [IF]
e: test-call-null
internals
0 ' call0 catch assert drop
;e
e: test-call-1023
internals
1023 ' call0 catch assert drop
;e
e: test-call-1024
internals
1024 ' call0 catch assert drop
;e
[THEN]
[THEN]

View File

@ -13,11 +13,57 @@
\ limitations under the License.
: dump-file ( a n a n -- )
w/o create-file if drop ." failed create-file" exit then
>r r@ write-file if r> drop ." failed write-file" exit then
w/o create-file throw
>r r@ write-file throw
r> close-file drop
;
: cp ( "src" "dst" -- )
bl parse r/o bin open-file throw { inf }
bl parse w/o bin create-file throw { outf }
begin
here 80 inf read-file throw
dup 0= if drop outf close-file throw inf close-file throw exit then
here swap outf write-file throw
again
;
: mv ( "src" "dst" -- ) bl parse bl parse rename-file throw ;
: rm ( "path" -- ) bl parse delete-file throw ;
: touch ( "path" -- )
bl parse 2dup w/o open-file
if drop w/o create-file throw then
close-file throw
;
internals definitions
: cremit ( ch -- ) dup nl = if drop cr else emit then ;
: crtype ( a n -- ) for aft dup c@ cremit 1+ then next drop ;
forth definitions internals
: cat ( "path" -- )
bl parse r/o bin open-file throw { fh }
begin
here 80 fh read-file throw
dup 0= if drop fh close-file throw exit then
here swap crtype
again
;
DEFINED? read-dir [IF]
: ls ( "path" -- )
bl parse dup 0= if 2drop s" ." then
open-dir throw { dh } begin
dh read-dir dup 0= if
2drop dh close-dir throw exit
then type cr
again
;
[THEN]
internals definitions
( Leave some room for growth of starting system. )
0 value saving-base

View File

@ -21,5 +21,6 @@ transfer forth
( Move heap to save point, with a gap. )
setup-saving-base
forth
execute ( assumes an xt for autoboot is on the dstack )
( assumes an xt for autoboot is on the dstack )
execute
ok

View File

@ -23,6 +23,18 @@
6 value precision
: set-precision ( n -- ) to precision ;
( Add recognizer for floats. )
also recognizers definitions
: REC-FNUM ( c-addr len -- f addr1 | addr2 )
s>float? if
['] afliteral RECTYPE-NUM
else
RECTYPE-NONE
then
;
' REC-FNUM +RECOGNIZER
previous definitions
internals definitions
: #f+s ( r -- ) fdup precision for aft 10e f* then next
precision for aft fdup f>s 10 mod [char] 0 + hold 0.1e f* then next

View File

@ -42,7 +42,8 @@
X("1/F", FINVERSE, *fp = 1.0f / *fp) \
X("S>F", STOF, *++fp = (float) tos; DROP) \
X("F>S", FTOS, DUP; tos = (cell_t) *fp--) \
XV(internals, "S>FLOAT?", FCONVERT, tos = fconvert((const char *) *sp, tos, fp)|0; --sp) \
XV(internals, "S>FLOAT?", FCONVERT, \
++fp; tos = fconvert((const char *) *sp, tos, fp)|0; if (!tos) --fp; --sp) \
Y(SFLOAT, DUP; tos = sizeof(float)) \
Y(SFLOATS, tos *= sizeof(float)) \
X("SFLOAT+", SFLOATPLUS, tos += sizeof(float)) \

View File

@ -26,6 +26,13 @@ also internals
>link
repeat drop ;
e: check-case
out: ENDOF
out: OF
out: ENDCASE
out: CASE
;e
e: check-locals
out: +to
out: to
@ -56,6 +63,8 @@ e: check-boot
out: tib
out: accept
out: echo
out: abort"
out: abort
out: z>s
out: s>z
out: r~
@ -86,6 +95,7 @@ e: check-boot
out: space
out: emit
out: bye
out: terminate
out: key?
out: key
out: type
@ -96,7 +106,6 @@ e: check-boot
out: value
out: throw
out: catch
out: handler
out: K
out: J
out: I
@ -106,10 +115,14 @@ e: check-boot
out: UNLOOP
out: ?do
out: do
out: used
out: remaining
out: fdepth
out: depth
out: postpone
out: next
out: for
out: nest-depth
out: postpone
out: postpone,
out: recurse
out: aft
out: repeat
@ -125,10 +138,6 @@ e: check-boot
out: char
out: [']
out: '
out: used
out: remaining
out: fdepth
out: depth
out: fp0
out: rp0
out: sp0
@ -184,6 +193,7 @@ e: check-tier1-opcodes
out: cell/
out: 2drop
out: 2dup
out: 3dup
out: 2@
out: 2!
@ -217,6 +227,7 @@ e: check-tier0-opcodes
out: literal
out: 0=
out: 0<
out: U<
out: +
out: U/MOD
out: */MOD
@ -307,6 +318,17 @@ e: check-float-opcodes
out: FSQRT
;e
e: check-files-dir
out: READ-DIR
out: CLOSE-DIR
out: OPEN-DIR
;e
e: check-files-dir-reverse
out: OPEN-DIR
out: CLOSE-DIR
;e
e: check-files
out: NON-BLOCK
out: FILE-SIZE
@ -368,6 +390,7 @@ e: check-blocks
;e
e: check-vocabulary
out: recognizers
out: internals
out: sealed
out: previous
@ -397,8 +420,8 @@ e: check-utils
out: str=
out: :noname
out: forget
out: spaces
out: dump
out: spaces
out: assert
;e
@ -409,6 +432,17 @@ e: check-snapshots
out: remember
out: restore
out: save
;e
e: check-fileops
DEFINED? open-dir [IF]
out: ls
[THEN]
out: cat
out: touch
out: rm
out: mv
out: cp
out: dump-file
;e
@ -425,6 +459,7 @@ e: check-ansi
e: check-tasks
out: start-task
out: task
out: pause?
out: pause
out: tasks
;e
@ -435,6 +470,7 @@ e: check-args
;e
e: check-imports
out: file-exists?
out: needs
out: required
out: included?
@ -466,20 +502,28 @@ e: check-opcodes
e: check-desktop
out: graphics
check-args
check-ansi
;e
e: check-filetools
out: visual
check-ansi
check-blocks
check-imports
check-snapshots
check-fileops
out: streams
out: ms
check-tasks
;e
e: check-asm
out: asm
;e
e: check-phase2
check-case
check-locals
check-asm
check-utils
;e
@ -494,6 +538,7 @@ e: test-windows-forth-voclist
out: tasks
out: windows
out: structures
out: recognizers
out: internalized
out: internals
out: FORTH
@ -515,9 +560,6 @@ e: test-windows-forth-namespace
out: ms
out: windows
check-phase1
out: GetProcAddress
out: LoadLibraryA
out: WindowProcShim
check-opcodes
out: forth-builtins
;e
@ -527,15 +569,16 @@ e: test-windows-forth-namespace
e: test-posix-forth-voclist
internals ' sockets voclist-from
out: sockets
out: termios
out: internals
out: graphics
out: ansi
out: editor
out: streams
out: tasks
out: termios
out: posix
out: structures
out: recognizers
out: internalized
out: internals
out: FORTH
@ -550,15 +593,20 @@ e: test-posix-forth-namespace
out: telnetd
out: sockets
out: x11
out: form
out: termios
check-desktop
check-filetools
check-phase2
out: form
out: termios
check-allocation
out: ok
out: pwd
out: rmdir
out: mkdir
out: cd
out: ms-ticks
out: ms
check-files-dir
check-files
out: default-key
out: default-type
@ -575,25 +623,22 @@ e: test-esp32-forth-voclist
internals ' ansi voclist-from
out: ansi
out: registers
out: oled
out: bluetooth
out: ansi
out: editor
out: streams
out: tasks
out: rtos
out: rmt
out: interrupts
out: sockets
out: Serial
out: ledc
out: SPIFFS
out: spi_flash
out: SD_MMC
out: SD
out: WiFi
out: Wire
out: ESP
out: editor
out: streams
out: tasks
out: structures
out: recognizers
out: internalized
out: internals
out: FORTH
@ -606,10 +651,6 @@ e: check-esp32-platform
out: INPUT
out: HIGH
out: LOW
out: page
out: tone
out: freq
out: duty
out: adc
out: pin
out: default-key?
@ -617,27 +658,51 @@ e: check-esp32-platform
out: default-type
;e
e: check-esp32-platform-flags
out: ESP32?
out: ESP32-S2?
out: ESP32-S3?
out: ESP32-C3?
out: PSRAM?
out: Xtensa?
out: RISC-V?
;e
e: check-esp32-builtins
check-esp32-platform-flags
out: pinMode
out: digitalWrite
out: digitalRead
out: analogRead
out: pulseIn
out: MS-TICKS
out: TERMINATE
check-files-reverse
check-files-dir-reverse
out: dacWrite
out: MDNS.begin
out: MDNS.addService
out: MDNS.setInstanceName
out: MDNS.addServiceTxt
;e
e: check-esp32-bindings
out: rtos
out: sockets
out: Serial
out: ledc
out: SPIFFS
out: SD_MMC
out: SD
out: WiFi
out: Wire
out: ESP
out: read-dir
;e
e: test-esp32-forth-namespace
' forth list-from
out: FORTH
out: camera-server
out: camera
out: telnetd
out: bterm
out: timers
out: registers
out: webui
out: login
@ -646,23 +711,9 @@ e: test-esp32-forth-namespace
out: web-interface
out: httpd
check-esp32-platform
out: oled
out: bluetooth
out: rtos
out: rmt
out: interrupts
out: sockets
out: Serial
out: ledc
out: SPIFFS
out: spi_flash
out: SD_MMC
out: SD
out: WiFi
out: Wire
out: ESP
check-filetools
check-phase2
check-esp32-bindings
check-allocation
check-phase1
check-esp32-builtins

View File

@ -65,10 +65,10 @@ gstack value gp
graphics definitions also internals
: box { left top w h }
left sx * tx + 16 arshift
top sy * ty + 16 arshift
w sx * 16 arshift
h sy * 16 arshift
left sx * tx + 16 arshift { l } l
top sy * ty + 16 arshift { t } t
left w + sx * tx + 16 arshift l -
top h + sy * ty + 16 arshift t -
raw-box
;

View File

@ -55,9 +55,11 @@ internals definitions
0 value included-files
: path-join { a a# b b# -- a n }
b if
b c@ [char] / = if 0 to a# then
then
a# b# + { r# } r# cell+ cell+ allocate throw { r }
2 cells +to r
b c@ [char] / = if 0 to a# then
begin b b# starts./ while
2 +to b -2 +to b#
a# b# + to r#
@ -78,11 +80,12 @@ forth definitions internals
: included ( a n -- )
sourcefilename >r >r
>r >r sourcedirname r> r> path-join 2dup sourcefilename!
['] raw-included catch
dup if ." Error including: " sourcefilename type cr then
['] raw-included catch if
." Error including: " sourcefilename type cr
-38 throw
then
sourcefilename& include+
r> r> sourcefilename!
throw ;
r> r> sourcefilename! ;
: include ( "name" -- ) bl parse included ;
@ -98,4 +101,6 @@ forth definitions internals
: required ( a n -- ) 2dup included? if 2drop else included then ;
: needs ( "name" -- ) bl parse required ;
: file-exists? ( "name" -- f ) r/o open-file if drop 0 else close-file throw -1 then ;
forth

View File

@ -53,3 +53,15 @@ e: test-needs
out: x.fs 2
out: x.fs 3
;e
e: test-path-join
also internals
s" /foo/bar/" s" /" path-join s" /" str= assert
s" /foo/bar/" s" baz" path-join s" /foo/bar/baz" str= assert
s" /foo/bar/" s" ./baz" path-join s" /foo/bar/baz" str= assert
s" /foo/bar/" s" ../baz" path-join s" /foo/baz" str= assert
s" /foo/bar/" s" baz/qux" path-join s" /foo/bar/baz/qux" str= assert
s" /foo/bar/" s" ./baz/qux" path-join s" /foo/bar/baz/qux" str= assert
s" /foo/bar/" s" " path-join s" /foo/bar/" str= assert
s" ./foo/" s" ../bar" path-join s" ./bar" str= assert
;e

View File

@ -32,11 +32,12 @@ static cell_t *forth_run(cell_t *init_rp) {
if (!init_rp) {
g_sys->DOCREATE_OP = ADDROF(DOCREATE);
g_sys->builtins = builtins;
forth_faults_setup();
return 0;
}
register cell_t *ip, *rp, *sp, tos, w;
register float *fp, ft;
rp = init_rp; UNPARK; NEXT;
rp = init_rp; UNPARK; FAULT_ENTRY; NEXT;
#define Z(flags, name, op, code) OP_ ## op: { code; } NEXT;
PLATFORM_OPCODE_LIST
TIER2_OPCODE_LIST

View File

@ -16,7 +16,8 @@
defer type
defer key
defer key?
defer bye
defer terminate
: bye 0 terminate ;
: emit ( n -- ) >r rp@ 1 type rdrop ;
: space bl emit ; : cr 13 emit nl emit ;
@ -56,9 +57,13 @@ variable hld
( Better Errors )
: notfound ( a n n -- )
if cr ." ERROR: " type ." NOT FOUND!" cr -1 throw then ;
dup if cr ." ERROR: " >r type r> ." NOT FOUND!" cr throw else drop then ;
' notfound 'notfound !
( Abort )
: abort -1 throw ;
: abort" postpone ." postpone cr -2 aliteral postpone throw ; immediate
( Input )
: raw.s depth 0 max for aft sp@ r@ cells - @ . then next ;
variable echo -1 echo ! variable arrow -1 arrow ! 0 value wascr
@ -95,18 +100,22 @@ create input-buffer input-limit allot
( Stack Guards )
sp0 'stack-cells @ 2 3 */ cells + constant sp-limit
: ?stack sp@ sp0 < if ." STACK UNDERFLOW " -1 throw then
sp-limit sp@ < if ." STACK OVERFLOW " -1 throw then ;
: ?stack sp@ sp0 < if ." STACK UNDERFLOW " -4 throw then
sp-limit sp@ < if ." STACK OVERFLOW " -3 throw then ;
( REPL )
: prompt ." ok" cr ;
: evaluate-buffer begin >in @ #tib @ < while evaluate1 ?stack repeat ;
: evaluate-buffer begin >in @ #tib @ < while ?stack +evaluate1 repeat ?stack ;
: evaluate ( a n -- ) 'tib @ >r #tib @ >r >in @ >r
#tib ! 'tib ! 0 >in ! evaluate-buffer
r> >in ! r> #tib ! r> 'tib ! ;
: quit begin ['] evaluate-buffer catch
if 0 state ! sp0 sp! fp0 fp! rp0 rp! ." ERROR" cr then
prompt refill drop again ;
: evaluate&fill
begin >in @ #tib @ >= if prompt refill drop then evaluate-buffer again ;
: quit
#tib @ >in !
begin ['] evaluate&fill catch
if 0 state ! sp0 sp! fp0 fp! rp0 rp! ." ERROR " cr then
again ;
variable boot-prompt
: free. ( nf nu -- ) 2dup swap . ." free + " . ." used = " 2dup + . ." total ("
over + 100 -rot */ n. ." % free)" ;
@ -114,4 +123,4 @@ variable boot-prompt
boot-prompt @ if boot-prompt @ execute then
." Forth dictionary: " remaining used free. cr
." 3 x Forth stacks: " 'stack-cells @ cells . ." bytes each" cr
prompt refill drop quit ;
quit ;

21
common/phase1.fs Normal file
View File

@ -0,0 +1,21 @@
\ Copyright 2023 Bradley D. Nelson
\
\ Licensed under the Apache License, Version 2.0 (the "License");
\ you may not use this file except in compliance with the License.
\ You may obtain a copy of the License at
\
\ http://www.apache.org/licenses/LICENSE-2.0
\
\ Unless required by applicable law or agreed to in writing, software
\ distributed under the License is distributed on an "AS IS" BASIS,
\ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
\ See the License for the specific language governing permissions and
\ limitations under the License.
needs comments.fs
needs boot.fs
needs io.fs
needs conditionals.fs
needs vocabulary.fs
needs floats.fs
needs structures.fs

23
common/phase1e.fs Normal file
View File

@ -0,0 +1,23 @@
\ Copyright 2023 Bradley D. Nelson
\
\ Licensed under the Apache License, Version 2.0 (the "License");
\ you may not use this file except in compliance with the License.
\ You may obtain a copy of the License at
\
\ http://www.apache.org/licenses/LICENSE-2.0
\
\ Unless required by applicable law or agreed to in writing, software
\ distributed under the License is distributed on an "AS IS" BASIS,
\ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
\ See the License for the specific language governing permissions and
\ limitations under the License.
needs comments.fs
needs tier2a_forth.fs
needs boot.fs
needs tier2b_forth.fs
needs io.fs
needs conditionals.fs
needs vocabulary.fs
needs floats.fs
needs structures.fs

View File

@ -1,4 +1,4 @@
\ Copyright 2021 Bradley D. Nelson
\ Copyright 2023 Bradley D. Nelson
\
\ Licensed under the Apache License, Version 2.0 (the "License");
\ you may not use this file except in compliance with the License.
@ -12,8 +12,7 @@
\ See the License for the specific language governing permissions and
\ limitations under the License.
needs ../posix/termios.fs
create keymap
: edit raw-mode begin key . again ;
needs utils.fs
needs code.fs
needs locals.fs
needs case.fs

18
common/phase_desktop.fs Normal file
View File

@ -0,0 +1,18 @@
\ Copyright 2023 Bradley D. Nelson
\
\ Licensed under the Apache License, Version 2.0 (the "License");
\ you may not use this file except in compliance with the License.
\ You may obtain a copy of the License at
\
\ http://www.apache.org/licenses/LICENSE-2.0
\
\ Unless required by applicable law or agreed to in writing, software
\ distributed under the License is distributed on an "AS IS" BASIS,
\ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
\ See the License for the specific language governing permissions and
\ limitations under the License.
needs desktop.fs
needs graphics.fs
needs graphics_utils.fs
needs heart.fs

21
common/phase_filetools.fs Normal file
View File

@ -0,0 +1,21 @@
\ Copyright 2023 Bradley D. Nelson
\
\ Licensed under the Apache License, Version 2.0 (the "License");
\ you may not use this file except in compliance with the License.
\ You may obtain a copy of the License at
\
\ http://www.apache.org/licenses/LICENSE-2.0
\
\ Unless required by applicable law or agreed to in writing, software
\ distributed under the License is distributed on an "AS IS" BASIS,
\ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
\ See the License for the specific language governing permissions and
\ limitations under the License.
needs tasks.fs
needs streams.fs
needs filetools.fs
needs including.fs
needs blocks.fs
needs ansi.fs
needs visual.fs

View File

@ -0,0 +1,32 @@
\ Copyright 2024 Bradley D. Nelson
\
\ Licensed under the Apache License, Version 2.0 (the "License");
\ you may not use this file except in compliance with the License.
\ You may obtain a copy of the License at
\
\ http://www.apache.org/licenses/LICENSE-2.0
\
\ Unless required by applicable law or agreed to in writing, software
\ distributed under the License is distributed on an "AS IS" BASIS,
\ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
\ See the License for the specific language governing permissions and
\ limitations under the License.
e: test-recognizers
also recognizers
also internals
: rec-blah ( a n -- rec )
s" blah" str= if
123 ['] aliteral rectype-num
else
rectype-none
then
;
' rec-blah +recognizer
: test blah . cr ;
-recognizer
previous
previous
test
out: 123
;e

View File

@ -17,25 +17,42 @@
vocabulary structures structures definitions
variable last-align
: typer ( align sz "name" ) create , ,
does> dup cell+ @ last-align ! @ ;
1 1 typer i8
2 2 typer i16
4 4 typer i32
cell 8 typer i64
cell cell typer ptr
long-size long-size typer long
variable last-typer
: typer ( xt@ xt! sz "name" -- )
create dup , 1 max cell min , , ,
does> dup last-typer ! dup cell+ @ last-align ! @ ;
: sc@ ( a -- c ) c@ dup 127 > if 256 - then ;
' sc@ ' c! 1 typer i8
' c@ ' c! 1 typer u8
' sw@ ' w! 2 typer i16
' uw@ ' w! 2 typer u16
' sl@ ' l! 4 typer i32
' ul@ ' l! 4 typer u32
' @ ' ! 8 typer i64 ( Wrong on 32-bit! )
' @ ' ! cell typer ptr
long-size cell = [IF]
: long ptr ;
[ELSE]
: long i32 ;
[THEN]
variable last-struct
: struct ( "name" ) 1 0 typer latestxt >body last-struct ! ;
: struct ( "name" ) 0 0 0 typer latestxt >body last-struct !
1 last-align ! ;
: align-by ( a n -- a ) 1- dup >r + r> invert and ;
: max! ( n a -- ) swap over @ max swap ! ;
: struct-align ( n -- )
dup last-struct @ cell+ @ max last-struct @ cell+ !
dup last-struct @ cell+ max!
last-struct @ @ swap align-by last-struct @ ! ;
: field ( n "name" )
last-align @ struct-align
create last-struct @ @ , last-struct @ +!
create last-struct @ @ , last-struct @ +! last-typer @ ,
does> @ + ;
: field-op ( n "name" -- )
>r ' dup >body cell+ @ r> cells + @
state @ if >r , r> , else >r execute r> execute then ;
: !field ( n "name" -- ) 2 field-op ; immediate
: @field ( "name" -- n ) 3 field-op ; immediate
forth definitions

View File

@ -46,3 +46,62 @@ e: test-nested-structure
1000 ->bar ->right 1012 =assert
1000 ->bar ->bottom 1016 =assert
;e
e: test-forth-structure
also structures
0 last-align !
struct foo
1 field t1
4 field t2
9 field t3
12 field t4
0 t1 0 =assert
0 t2 1 =assert
0 t3 5 =assert
0 t4 14 =assert
;e
e: test-structure-accessors
also structures
struct foo
i8 field ->a
u8 field ->b
i16 field ->c
u16 field ->d
i32 field ->e
u32 field ->f
ptr field ->g
pad foo erase
127 pad !field ->a
255 pad !field ->b
32767 pad !field ->c
65535 pad !field ->d
2147483647 pad !field ->e
4294967295 pad !field ->f
1234 pad !field ->g
127 pad @field ->a =assert
255 pad @field ->b =assert
32767 pad @field ->c =assert
65535 pad @field ->d =assert
2147483647 pad @field ->e =assert
4294967295 pad @field ->f =assert
1234 pad @field ->g =assert
-128 pad !field ->a
0 pad !field ->b
-32768 pad !field ->c
0 pad !field ->d
-2147483648 pad !field ->e
0 pad !field ->f
1234 pad !field ->g
-128 pad @field ->a =assert
0 pad @field ->b =assert
-32768 pad @field ->c =assert
0 pad @field ->d =assert
-2147483648 pad @field ->e =assert
0 pad @field ->f =assert
1234 pad @field ->g =assert
;e

View File

@ -28,6 +28,9 @@ forth definitions tasks also internals
task-list @ cell+ @ sp! rp!
;
( Check if there are other tasks. )
: pause? ( -- f ) task-list @ dup @ <> ;
: task ( xt dsz rsz "name" )
create here >r 0 , 0 , ( link, sp )
swap here cell+ r@ cell+ ! cells allot

View File

@ -14,17 +14,6 @@
also ansi also internals
DEFINED? windows [IF]
also windows
: sysexit ( n -- ) ExitProcess ;
[ELSE]
DEFINED? posix [IF]
also posix
[ELSE]
: sysexit ( n -- ) terminate ;
[THEN]
[THEN]
( Support for eval tests )
40000 constant expect-limit
create expect-buffer expect-limit allot
@ -98,8 +87,23 @@ variable tests-found variable tests-run variable tests-passed
: check-fresh depth if }confirm ." DEPTH LEAK! " depth . 1 throw then
fdepth if }confirm ." FDEPTH LEAK! " fdepth . 1 throw then ;
: wrap-test ( xt -- ) expect-reset >r check-fresh r> execute check-fresh expect-finish ;
: red 1 fg ; : green 2 fg ; : hr 40 for [char] - emit next cr ;
: replace-line 13 emit clear-to-eol ;
: red ; : green ; : replace-line cr ; : old-normal normal ; : normal ;
DEFINED? posix [IF]
also posix stdout isatty previous [IF]
: red 1 fg ; : green 2 fg ;
: replace-line 13 emit clear-to-eol ;
: normal old-normal ;
[THEN]
[THEN]
( TODO: Figure out how to detect console in windows. )
(
DEFINED? windows [IF]
: red 1 fg ; : green 2 fg ;
: replace-line 13 emit clear-to-eol ;
: normal old-normal ;
[THEN]
)
: hr 40 for [char] - emit next cr ;
: label-test ( xt -- ) replace-line >name type ;
: run-test ( xt -- ) dup label-test only forth confirm{ ['] wrap-test catch }confirm
if drop ( cause xt restored on throw ) red ." FAILED" normal cr
@ -117,5 +121,5 @@ variable tests-found variable tests-run variable tests-passed
: run-tests
reset-test-counters ['] count-test for-tests
['] run-test for-tests show-test-results
tests-passed @ tests-found @ <> sysexit ;
tests-passed @ tests-found @ <> terminate ;
only forth

View File

@ -0,0 +1,76 @@
\ Copyright 2021 Bradley D. Nelson
\
\ Licensed under the Apache License, Version 2.0 (the "License");
\ you may not use this file except in compliance with the License.
\ You may obtain a copy of the License at
\
\ http://www.apache.org/licenses/LICENSE-2.0
\
\ Unless required by applicable law or agreed to in writing, software
\ distributed under the License is distributed on an "AS IS" BASIS,
\ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
\ See the License for the specific language governing permissions and
\ limitations under the License.
( Testing thrown values )
e: test-abort
' abort catch -1 =assert
;e
e: test-abort"
: test abort" doh!" ;
' test catch -2 =assert
out: doh!
;e
( Skip on ESP32 as not emulated. )
DEFINED? esp 0= [IF]
e: test-0/
123 0 ' / catch -10 =assert
0 =assert 123 =assert
;e
e: test-0mod
123 0 ' mod catch -10 =assert
0 =assert 123 =assert
;e
e: test-0*/
123 456 0 ' */ catch -10 =assert
0 =assert 456 =assert 123 =assert
;e
e: test-0*/mod
123 456 0 ' */mod catch -10 =assert
0 =assert 456 =assert 123 =assert
;e
e: test-0/mod
123 0 ' /mod catch -10 =assert
0 =assert 123 =assert
;e
e: test-bad-load
0 ' @ catch -9 =assert
0 =assert
;e
e: test-bad-store
123 0 ' ! catch -9 =assert
0 =assert 123 =assert
;e
( Skip on win64 because wine can't handle these, unsure why. )
DEFINED? windows 0= cell 4 = or [IF]
e: test-bad-execute
internals
0 ' call0 catch -9 =assert
0 =assert
;e
[THEN]
[THEN]

View File

@ -32,8 +32,11 @@ typedef uintptr_t ucell_t;
#define DUP (*++sp = tos)
#define PUSH DUP; tos = (cell_t)
#define PARK DUP; *++rp = (cell_t) fp; *++rp = (cell_t) sp; *++rp = (cell_t) ip
#define UNPARK ip = (cell_t *) *rp--; sp = (cell_t *) *rp--; fp = (float *) *rp--; DROP
#define PARK *++rp = (cell_t) ip; *++rp = (cell_t) fp; DUP; *++rp = (cell_t) sp;
#define UNPARK sp = (cell_t *) *rp--; DROP; fp = (float *) *rp--; ip = (cell_t *) *rp--;
#define THROWIT(n) \
rp = *g_sys->throw_handler; *g_sys->throw_handler = (cell_t *) *rp--; UNPARK; tos = (n);
#define TOFLAGS(xt) ((uint8_t *) (((cell_t *) (xt)) - 1))
#define TONAMELEN(xt) (TOFLAGS(xt) + 1)
@ -63,10 +66,30 @@ typedef int64_t dcell_t;
# error "unsupported cell size"
# endif
# define SSMOD_FUNC dcell_t d = (dcell_t) *sp * (dcell_t) sp[-1]; \
--sp; cell_t a = (cell_t) (d < 0 ? ~(~d / tos) : d / tos); \
--sp; cell_t a = (cell_t) (d / tos); \
a = a * tos == d ? a : a - ((d < 0) ^ (tos < 0)); \
*sp = (cell_t) (d - ((dcell_t) a) * tos); tos = a
#endif
#ifdef WEB_DUMP
// Use */mod as the base for the web version.
# define SLASHMOD_FUNC DUP; *sp = 1; SSMOD_FUNC
# define SLASH_FUNC SLASHMOD_FUNC; NIP
# define MOD_FUNC SLASHMOD_FUNC; DROP
# define CELLSLASH_FUNC DUP; tos = sizeof(cell_t); SLASH_FUNC
#else
// Use separate versions for non-web so throw has the right depth.
# define SLASHMOD_FUNC cell_t d = *sp; cell_t a = d / tos; \
cell_t b = a * tos == d ? a : a - ((d < 0) ^ (tos < 0)); \
*sp = d - b * tos; tos = b
# define SLASH_FUNC cell_t d = *sp; cell_t a = d / tos; NIP; \
tos = a * tos == d ? a : a - ((d < 0) ^ (tos < 0))
# define MOD_FUNC cell_t d = *sp; cell_t a = d / tos; \
cell_t b = a * tos == d ? a : a - ((d < 0) ^ (tos < 0)); \
NIP; tos = d - b * tos
# define CELLSLASH_FUNC tos = tos < 0 ? ~(~tos / sizeof(cell_t)) : tos / sizeof(cell_t)
#endif
typedef struct {
const char *name;
union {
@ -83,6 +106,7 @@ typedef struct {
YV(internals, NOP, ) \
X("0=", ZEQUAL, tos = !tos ? -1 : 0) \
X("0<", ZLESS, tos = (tos|0) < 0 ? -1 : 0) \
X("U<", ULESS, tos = ((ucell_t) *sp) < ((ucell_t) tos) ? -1 : 0; --sp) \
X("+", PLUS, tos += *sp--) \
X("U/MOD", USMOD, w = *sp; *sp = (ucell_t) w % (ucell_t) tos; \
tos = (ucell_t) w / (ucell_t) tos) \

View File

@ -13,13 +13,16 @@
// limitations under the License.
#define TIER1_OPCODE_LIST \
XV(internals, "0", ZERO, PUSH 0) \
XV(internals, "1", ONE, PUSH 1) \
XV(internals, "-1", NEGATIVEONE, PUSH -1) \
Y(nip, NIP) \
Y(rdrop, --rp) \
XV(forth, "*/", STARSLASH, SSMOD_FUNC; NIP) \
X("*", STAR, tos *= *sp--) \
X("/mod", SLASHMOD, DUP; *sp = 1; SSMOD_FUNC) \
X("/", SLASH, DUP; *sp = 1; SSMOD_FUNC; NIP) \
Y(mod, DUP; *sp = 1; SSMOD_FUNC; DROP) \
X("/mod", SLASHMOD, SLASHMOD_FUNC) \
X("/", SLASH, SLASH_FUNC) \
X("mod", MOD, MOD_FUNC) \
Y(invert, tos = ~tos) \
Y(negate, tos = -tos) \
X("-", MINUS, tos = (*sp--) - tos) \
@ -44,9 +47,10 @@
X("+!", PLUSSTORE, *((cell_t *) tos) += *sp--; DROP) \
X("cell+", CELLPLUS, tos += sizeof(cell_t)) \
Y(cells, tos *= sizeof(cell_t)) \
X("cell/", CELLSLASH, DUP; tos = sizeof(cell_t); DUP; *sp = 1; SSMOD_FUNC; NIP) \
X("cell/", CELLSLASH, CELLSLASH_FUNC) \
X("2drop", TWODROP, NIP; DROP) \
X("2dup", TWODUP, DUP; tos = sp[-1]; DUP; tos = sp[-1]) \
X("3dup", THREEDUP, sp += 3; sp[-2] = tos; sp[-1] = sp[-4]; *sp = sp[-3]) \
X("2@", TWOAT, DUP; *sp = *(cell_t *) tos; tos = ((cell_t *) tos)[1]) \
X("2!", TWOSTORE, *(cell_t *) tos = sp[-1]; \
((cell_t *) tos)[1] = *sp; sp -= 2; DROP) \
@ -80,6 +84,7 @@
XV(internals, "'argc", ARGC, DUP; tos = (cell_t) &g_sys->argc) \
XV(internals, "'argv", ARGV, DUP; tos = (cell_t) &g_sys->argv) \
XV(internals, "'runner", RUNNER, DUP; tos = (cell_t) &g_sys->runner) \
XV(internals, "'throw-handler", TTHROW_HANDLER, DUP; tos = (cell_t) &g_sys->throw_handler) \
Y(context, DUP; tos = (cell_t) (g_sys->context + 1)) \
Y(latestxt, DUP; tos = (cell_t) g_sys->latestxt) \
XV(forth_immediate, "[", LBRACKET, g_sys->state = 0) \

View File

@ -17,12 +17,39 @@
( For tests and asserts )
: assert ( f -- ) 0= throw ;
( Print spaces )
: spaces ( n -- ) 0 max for aft space then next ;
internals definitions
( Temporary for platforms without CALLCODE )
DEFINED? CALLCODE 0= [IF]
create CALLCODE
[THEN]
( Safe memory access, i.e. aligned )
cell 1- constant cell-mask
: cell-base ( a -- a ) cell-mask invert and ;
: cell-shift ( a -- a ) cell-mask and 8 * ;
: ca@ ( a -- n ) dup cell-base @ swap cell-shift rshift 255 and ;
( Print address line leaving room )
: dump-line ( a -- a ) cr <# #s #> 20 over - >r type r> spaces ;
( Semi-dangerous word to trim down the system heap )
DEFINED? realloc [IF]
: relinquish ( n -- ) negate 'heap-size +! 'heap-start @ 'heap-size @ realloc drop ;
[THEN]
forth definitions internals
( Examine Memory )
: dump ( a n -- )
cr 0 swap for dup 16 mod 0= if cr then 2dup + c@ . 1+ next 2drop cr ;
( Print spaces )
: spaces ( n -- ) for aft space then next ;
over 15 and if over dump-line over 15 and 3 * spaces then
for aft
dup 15 and 0= if dup dump-line then
dup ca@ <# # #s #> type space 1+
then next drop cr ;
( Remove from Dictionary )
: forget ( "name" ) ' dup >link current @ ! >name drop here - allot ;
@ -112,9 +139,10 @@ variable indent
?see-flags cr
exit
then
dup >flags BUILTIN_FORK and if ." Built-in fork: " see. exit then
dup >flags BUILTIN_FORK and if ." Built-in-fork: " see. exit then
dup @ ['] input-buffer @ = if ." CREATE/VARIABLE: " see. cr exit then
dup @ ['] SMUDGE @ = if ." DOES>/CONSTANT: " see. cr exit then
dup @ ['] callcode @ = if ." Code: " see. cr exit then
dup >params 0= if ." Built-in: " see. cr exit then
." Unsupported: " see. cr ;

View File

@ -13,6 +13,7 @@
\ limitations under the License.
( Tests of utils.fs )
e: test-.s0
.s
out: <0>
@ -255,3 +256,9 @@ e: test-see-immediate
out: 123
out: ; IMMEDIATE
;e
e: test-negative-spaces
: foo -10 spaces ." hi" cr ;
foo
out: hi
;e

167
common/visual.fs Normal file
View File

@ -0,0 +1,167 @@
\ Copyright 2021 Bradley D. Nelson
\
\ Licensed under the Apache License, Version 2.0 (the "License");
\ you may not use this file except in compliance with the License.
\ You may obtain a copy of the License at
\
\ http://www.apache.org/licenses/LICENSE-2.0
\
\ Unless required by applicable law or agreed to in writing, software
\ distributed under the License is distributed on an "AS IS" BASIS,
\ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
\ See the License for the specific language governing permissions and
\ limitations under the License.
( Lazy loaded visual editor. )
: visual r|
also DEFINED? termios [IF] termios [THEN]
also internals
also ansi
also forth
current @
vocabulary visual visual definitions
vocabulary insides insides definitions
256 constant max-path
create filename max-path allot 0 value filename#
0 value fileh
10 constant start-size
start-size allocate throw value text
start-size value capacity
0 value length
0 value caret
: up ( n -- n ) begin dup 0 > over text + c@ nl <> and while 1- repeat 1- 0 max ;
: nup ( n -- n ) 10 for up next ;
: down ( n -- n ) begin dup length < over text + c@ nl <> and while 1+ repeat 1+ length min ;
: ndown ( n -- n ) 10 for down next ;
: update
caret nup dup 0<> if 1+ 1+ then { before }
before ndown ndown { after }
page
text before + caret before - crtype
caret length < text caret + c@ nl <> and if
1 bg text caret + c@ emit normal
text caret + 1+ after caret - 1- 0 max crtype
else
1 bg space normal
text caret + after caret - crtype
then normal
;
: insert ( ch -- )
length capacity = if text capacity 1+ 2* >r r@ 1+ resize throw to text r> to capacity then
text caret + dup 1+ length caret - cmove>
text caret + c!
1 +to caret
1 +to length
update
;
: handle-esc
key
dup [char] [ = if drop
key
dup [char] A = if drop caret up to caret update exit then
dup [char] B = if drop caret down to caret update exit then
dup [char] C = if drop caret 1+ length min to caret update exit then
dup [char] D = if drop caret 1- 0 max to caret update exit then
dup [char] 5 = if drop key drop caret 8 for up next to caret update exit then
dup [char] 6 = if drop key drop caret 8 for down next to caret update exit then
drop
exit
then
drop
;
: delete
length caret > if
text caret + dup 1+ swap length caret - 1- 0 max cmove
-1 +to length
update
then
;
: backspace
caret 0 > if
-1 +to caret
delete
then
;
: load ( a n -- )
0 to caret
dup to filename#
filename swap cmove
filename filename# r/o open-file 0= if
to fileh
fileh file-size throw to capacity
text capacity 1+ resize throw to text
capacity to length
text length fileh read-file throw drop
fileh close-file throw
else
drop
0 to capacity
0 to length
then
;
: save
filename filename# w/o create-file throw to fileh
text length fileh write-file throw
fileh close-file throw
;
: quit-edit
page filename filename# type cr ." SAVE? "
begin
key 95 and
dup [char] Y = if drop save 123 throw then
dup [char] N = if drop 123 throw then
drop
again
;
: handle-key ( ch -- )
dup 27 = if drop handle-esc exit then
dup [char] D [char] @ - = if delete exit then
dup [char] H [char] @ - = over 127 = or if drop backspace exit then
dup [char] L [char] @ - = if drop update exit then
( Support either Ctrl-S or Ctrl-P )
dup [char] S [char] @ - =
over [char] P [char] @ - = or
if drop save update ." saved" exit then
dup [char] X [char] @ - = if drop quit-edit then
dup [char] Q [char] @ - = if drop quit-edit then
dup 13 = if drop nl insert exit then
dup bl >= if insert else drop then
;
: ground depth 0<> throw ;
: step *key handle-key ground ;
DEFINED? raw-mode 0= [IF]
: raw-mode ;
: normal-mode ;
[THEN]
: run
raw-mode update
begin
['] step catch
dup 123 = if drop normal-mode page exit then
if ." FAILURE!" then
again
;
visual definitions insides
: edit ( <filename> ) bl parse load run ;
previous previous previous previous current ! visual
| evaluate ;

View File

@ -55,15 +55,16 @@ transfer{
voc-stack-end last-vocabulary notfound
*key *emit wascr eat-till-cr
immediate? input-buffer ?echo ?arrow. arrow
evaluate-buffer aliteral value-bind
evaluate-buffer evaluate&fill aliteral value-bind
leaving( )leaving leaving leaving,
parse-quote digit $@ raw.s
tib-setup input-limit sp-limit ?stack
[SKIP] [SKIP]' raw-ok boot-prompt free.
$place zplace BUILTIN_MARK
nest-depth handler +evaluate1 do-notfound interpret0
}transfer
( Move branching opcodes to separate vocabulary )
( Move branching opcodes to separate vocabulary. )
vocabulary internalized internalized definitions
: cleave ' >link xt-transfer ;
cleave begin cleave again cleave until
@ -72,7 +73,17 @@ cleave else cleave while cleave repeat
cleave aft cleave for cleave next
cleave do cleave ?do cleave +loop
cleave loop cleave leave
forth definitions
( Move recognizers to separate vocabulary )
vocabulary recognizers recognizers definitions
transfer{
REC-FIND REC-NUM
RECTYPE: RECTYPE-NONE RECTYPE-WORD RECTYPE-IMM RECTYPE-NUM
SET-RECOGNIZERS GET-RECOGNIZERS
-RECOGNIZER +RECOGNIZER RECSTACK
RECOGNIZE
}transfer
forth definitions
( Make DOES> switch to compile mode when interpreted )

587
configure.py Executable file
View File

@ -0,0 +1,587 @@
#! /usr/bin/env python3
# Copyright 2023 Bradley D. Nelson
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import argparse
import os
import sys
import subprocess
SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
ROOT_DIR = SCRIPT_DIR
NINJA_BUILD = os.path.join(ROOT_DIR, 'build.ninja')
FAST = False
SRC_DIR = os.path.relpath(ROOT_DIR, os.getcwd())
if SRC_DIR == '.':
DST_DIR = 'out'
NINJA_DIR = '.'
else:
DST_DIR = '.'
NINJA_DIR = '.'
CFLAGS_COMMON = [
'-O2',
'-I', '$src',
'-I', '$dst',
]
CFLAGS_MINIMIZE = [
'-s',
'-DUEFORTH_MINIMAL',
'-fno-exceptions',
'-ffreestanding',
'-fno-stack-protector',
'-fomit-frame-pointer',
'-fno-ident',
'-ffunction-sections', '-fdata-sections',
'-fmerge-all-constants',
]
if sys.platform == 'linux':
CFLAGS_MINIMIZE.append('-Wl,--build-id=none')
CFLAGS = CFLAGS_COMMON + CFLAGS_MINIMIZE + [
'-std=c++11',
'-Wall',
'-Werror',
'-no-pie',
'-Wl,--gc-sections',
]
if sys.platform == 'darwin':
CFLAGS += [
'-Wl,-dead_strip',
'-D_GNU_SOURCE',
]
elif sys.platform == 'linux':
CFLAGS += [
'-s',
'-Wl,--gc-sections',
'-no-pie',
'-Wl,--build-id=none',
]
STRIP_ARGS = ['-S']
if sys.platform == 'darwin':
STRIP_ARGS += ['-x']
elif sys.platform == 'linux':
STRIP_ARGS += [
'--strip-unneeded',
'--remove-section=.note.gnu.gold-version',
'--remove-section=.comment',
'--remove-section=.note',
'--remove-section=.note.gnu.build-id',
'--remove-section=.note.ABI-tag',
]
LIBS = ['-ldl']
WIN_CFLAGS = CFLAGS_COMMON
WIN_LIBS = ['user32.lib']
WIN_LFLAGS32 = []
WIN_LFLAGS64 = []
WEB_ENABLED = False
PICO_ICE_ENABLED = False
D8_AVAILABLE = False
D8 = 'UNSUPPORTED'
WINDOWS_ENABLED = False
WINTMP = '/UNSUPPORTED'
WIN_CL32 = 'UNSUPPORTED'
WIN_CL64 = 'UNSUPPORTED'
WIN_LINK32 = 'UNSUPPORTED'
WIN_LINK64 = 'UNSUPPORTED'
WIN_RC32 = 'UNSUPPORTED'
WIN_RC64 = 'UNSUPPORTED'
ARDUINO_CLI = 'UNSUPPORTED'
# Mutable global state.
build_files = []
output = ''
defaults = []
versions = {}
def Escape(path):
return path.replace(' ', '\\ ').replace('(', '\\(').replace(')', '\\)')
def LSQ(path):
return '"' + str(subprocess.check_output('ls ' + Escape(path), shell=True,
stderr=subprocess.DEVNULL), 'ascii').splitlines()[0] + '"'
def DetectWindowsTools(args):
global WINDOWS_ENABLED
global WINTMP, ARDUINO_CLI
global WIN_CL32, WIN_CL64, WIN_LINK32, WIN_LINK64, WIN_RC32, WIN_RC64
try:
LOCALAPPDATAR = str(subprocess.check_output('cmd.exe /c echo "%LOCALAPPDATA%"', shell=True,
stderr=subprocess.DEVNULL).splitlines()[0], 'ascii').replace('\\', '/')
except:
if not args.quiet:
sys.stderr.write('Windows %LOCALAPPDATA% not available, Windows support disabled.\n')
return
LOCALAPPDATA = LOCALAPPDATAR.replace('C:/', '/mnt/c/')
ARDUINO_CLI = LOCALAPPDATA + '/Programs/arduino-ide/resources/app/lib/backend/resources/arduino-cli.exe'
WINTMP = LOCALAPPDATA + '/Temp'
WINTMPR = LOCALAPPDATAR + '/Temp'
PROGFILES = '/mnt/c/Program Files'
PROGFILES_X86 = '/mnt/c/Program Files (x86)'
MSVS = PROGFILES + '/Microsoft Visual Studio'
MSKITS = PROGFILES_X86 + '/Windows Kits'
try:
WIN_CL32 = LSQ(MSVS + '/*/*/VC/Tools/MSVC/*/bin/Hostx86/x86/cl.exe')
WIN_CL64 = LSQ(MSVS + '/*/*/VC/Tools/MSVC/*/bin/Hostx86/x64/cl.exe')
WIN_LINK32 = LSQ(MSVS + '/*/*/VC/Tools/MSVC/*/bin/Hostx86/x86/link.exe')
WIN_LINK64 = LSQ(MSVS + '/*/*/VC/Tools/MSVC/*/bin/Hostx86/x64/link.exe')
WIN_RC32 = LSQ(MSKITS + '/*/bin/*/x86/rc.exe')
WIN_RC64 = LSQ(MSKITS + '/*/bin/*/x64/rc.exe')
WIN_TOOL_ROOT = WIN_CL32.replace('/mnt/c/', 'c:/').replace('/bin/Hostx86/x86/cl.exe', '').replace('"', '')
WINDOWS_H = LSQ(MSKITS + '/*/Include/*/um/windows.h')
WINKIT_HEADERS = WINDOWS_H.replace('/mnt/c/', 'c:/').replace('/um/windows.h', '').replace('"', '')
WINKIT_LIBS = WINKIT_HEADERS.replace('/Include/', '/Lib/')
WIN_CFLAGS.extend([
'-I', '"%s/include"' % WIN_TOOL_ROOT,
'-I', '"%s/um"' % WINKIT_HEADERS,
'-I', '"%s/ucrt"' % WINKIT_HEADERS,
'-I', '"%s/shared"' % WINKIT_HEADERS,
])
WIN_LFLAGS32.extend([
'/LIBPATH:"%s/lib/x86"' % WIN_TOOL_ROOT,
'/LIBPATH:"%s/ucrt/x86"' % WINKIT_LIBS,
'/LIBPATH:"%s/um/x86"' % WINKIT_LIBS,
])
WIN_LFLAGS64.extend([
'/LIBPATH:"%s/lib/x64"' % WIN_TOOL_ROOT,
'/LIBPATH:"%s/ucrt/x64"' % WINKIT_LIBS,
'/LIBPATH:"%s/um/x64"' % WINKIT_LIBS,
])
except:
if not args.quiet:
sys.stderr.write('Windows tools not available, Windows support disabled.\n')
return
try:
LSQ('/usr/bin/convert')
except:
if not args.quiet:
sys.stderr.write('Windows build requires ImageMagick (/usr/bin/convert).\n')
sys.stderr.write('Windows support disabled.\n')
return
WINDOWS_ENABLED = True
def DetectGenericTools(args):
global D8, D8_AVAILABLE, WEB_ENABLED, PICO_ICE_ENABLED
try:
D8 = LSQ('${HOME}/src/v8/v8/out/x64.release/d8')
D8_AVAILABLE = True
except:
if not args.quiet:
sys.stderr.write('V8 checkout in $HOME/src/v8 not found, '
'disabling asm.js tests.\n')
try:
LSQ('/usr/bin/nodejs')
WEB_ENABLED = True
except:
if not args.quiet:
sys.stderr.write('/usr/bin/nodejs not found, disabling web.\n')
try:
LSQ('/usr/bin/arm-none-eabi-gcc')
PICO_ICE_ENABLED = True
except:
if not args.quiet:
sys.stderr.write('Missing package gcc-arm-none-eabi, pico-ice disabled.\n')
def FastOption():
if FAST:
return '-f'
else:
return ''
def SetVersions(**kwargs):
versions.update(kwargs)
def SelectHeader():
version = versions['version']
stable = versions['stable']
old_stable = versions['old_stable']
return f"""
ninja_required_version = 1.1
VERSION = {version}
STABLE_VERSION = {stable}
OLD_STABLE_VERSION = {old_stable}
"""
def InitOutput():
global output
output = f"""
src = {SRC_DIR}
dst = {DST_DIR}
ninjadir = {NINJA_DIR}
builddir = $dst
CFLAGS = {' '.join(CFLAGS)}
STRIP_ARGS = {' '.join(STRIP_ARGS)}
LIBS = {' '.join(LIBS)}
CXX = g++
WIN_CL32 = {WIN_CL32}
WIN_CL64 = {WIN_CL64}
WIN_LINK32 = {WIN_LINK32}
WIN_LINK64 = {WIN_LINK64}
WIN_RC32 = {WIN_RC32}
WIN_RC64 = {WIN_RC64}
D8 = {D8}
WIN_CFLAGS = {' '.join(WIN_CFLAGS)}
WIN_LFLAGS32 = {' '.join(WIN_LFLAGS32)}
WIN_LFLAGS64 = {' '.join(WIN_LFLAGS64)}
WIN_LIBS = {' '.join(WIN_LIBS)}
rule config
description = CONFIG
command = $src/configure.py -q {FastOption()}
rule revstamp
description = REVSTAMP
command = $in $src $out
build $dst/gen/REVISION $dst/gen/REVSHORT: revstamp $src/tools/revstamp.py
rule importation
description = IMPORTATION $in
depfile = $out.d
deps = gcc
command = $src/tools/importation.py -i $in -o $out -I $dst -I $src $options \
--depsout $depfile \
-DVERSION=$VERSION \
-DSTABLE_VERSION=$STABLE_VERSION \
-DOLD_STABLE_VERSION=$OLD_STABLE_VERSION \
-FREVISION=$dst/gen/REVISION \
-FREVSHORT=$dst/gen/REVSHORT
rule compile
description = CXX $in
depfile = $out.d
deps = gcc
command = $CXX $CFLAGS $in -o $out $LIBS -MD -MF $depfile && strip $STRIP_ARGS $out
rule compile_sim
description = CXX_SIM $in
depfile = $out.d
deps = gcc
command = $CXX -DUEFORTH_SIM=1 $CFLAGS $in -o $out $LIBS -MD -MF $depfile && strip $STRIP_ARGS $out
rule compile_win32
description = WIN_CL32 $in
deps = msvc
command = $WIN_CL32 /showIncludes /nologo /c /Fo$out $WIN_CFLAGS $in | $src/tools/posixify.py && touch $out
rule compile_win64
description = WIN_CL64 $in
deps = msvc
command = $WIN_CL64 /showIncludes /nologo /c /Fo$out $WIN_CFLAGS $in | $src/tools/posixify.py && touch $out
rule link_win32
description = WIN_LINK32 $in
command = $WIN_LINK32 /nologo /OUT:$out $WIN_LFLAGS32 $WIN_LIBS $in && touch $out && chmod a+x $out
rule link_win64
description = WIN_LINK64 $in
command = $WIN_LINK64 /nologo /OUT:$out $WIN_LFLAGS64 $WIN_LIBS $in && touch $out && chmod a+x $out
rule rc_win32
description = WIN_RC32 $in
command = $WIN_RC32 /nologo /i $src /fo $out $in && touch $out
rule rc_win64
description = WIN_RC64 $in
command = $WIN_RC64 /nologo /i $src /fo $out $in && touch $out
rule run
description = RUN $in
command = $in >$out
rule cmd
description = CMD $out
command = $cmd
rule resize
description = RESIZE $size
command = convert -resize $size $in $out
rule convert_image
description = IMAGE_CONVERT $in
command = convert $in $out
rule zip
description = ZIP
command = rm -f $out && cd $base && zip $relout $relin >/dev/null
rule copy
description = COPY $in
command = cp $in $out
rule gen_run
description = GEN_RUN $script
command = $script $options $infiles >$out
rule oneshot
description = ONESHOT
command = echo oneshot
rule forth_test
description = FORTH_TEST $test
depfile = $out.d
deps = gcc
command = $src/tools/importation.py -i $test -o $out --depsout $depfile --no-out && $interp $forth $test >$out 2>&1
rule publish
description = PUBLISH $pubpath
command = $src/tools/publish.py --src $in --dst "$pubpath" \
-DVERSION=$VERSION \
-DSTABLE_VERSION=$STABLE_VERSION \
-DOLD_STABLE_VERSION=$OLD_STABLE_VERSION \
-FREVISION=$dst/gen/REVISION \
-FREVSHORT=$dst/gen/REVSHORT >/dev/null 2>&1
rule clean
description = CLEAN
command = rm -rf $dst/
build clean: clean
rule all_clean
description = ALL_CLEAN
command = rm -rf $dst/ && rm build.ninja
build allclean: all_clean
pool serial
depth = 1
"""
def Importation(target, source, header_mode='cpp', name=None, keep=False, deps=None, implicit=[], options=''):
global output
if keep:
options += ' --keep-first-comment'
if name:
options += ' --name ' + name + ' --header ' + header_mode
implicit = ' '.join(implicit)
output += f'build {target}: importation {source} | $dst/gen/REVISION $dst/gen/REVSHORT {implicit}\n'
if options:
output += f' options = {options}\n'
if deps:
output += f' depfile = {deps}\n'
return target
def Simple(op, target, source, implicit=[]):
global output
implicit = ' '.join(implicit)
output += f'build {target}: {op} {source} | {implicit}\n'
return target
def Compile(target, source, implicit=[]):
return Simple('compile', target, source, implicit)
def CompileSim(target, source, implicit=[]):
return Simple('compile_sim', target, source, implicit)
def CompileW32(target, source, implicit=[]):
return Simple('compile_win32', target, source, implicit)
def CompileW64(target, source, implicit=[]):
return Simple('compile_win64', target, source, implicit)
def LinkW32(target, source, implicit=[]):
return Simple('link_win32', target, source, implicit)
def LinkW64(target, source, implicit=[]):
return Simple('link_win64', target, source, implicit)
def ResizeImage(target, source, size, implicit=[]):
global output
Simple('resize', target, source, implicit)
output += f' size={size}\n'
return target
def ConvertImage(target, source, implicit=[]):
return Simple('convert_image', target, source, implicit)
def CompileResource32(target, source, implicit=[]):
return Simple('rc_win32', target, source, implicit)
def CompileResource64(target, source, implicit=[]):
return Simple('rc_win64', target, source, implicit)
def Run(target, source, implicit=[]):
return Simple('run', target, source, implicit)
def Zip(target, sources, base):
global output
ret = Simple('zip', target, ' '.join(sources))
relin = ' '.join([os.path.relpath(i, base) for i in sources])
relout = os.path.relpath(target, base)
output += f' base = {base}\n'
output += f' relout = {relout}\n'
output += f' relin = {relin}\n'
return ret
def Alias(target, source):
global output
output += f'build {target}: phony {source}\n'
return target
def Shortcut(target, source, command, **kwargs):
return Alias(target, Command('$dst/gen/' + target + '.not', source, command, **kwargs))
def Copy(target, source):
global output
output += f'build {target}: copy {source}\n'
return target
def GenRun(target, script, options, sources):
sources = ' '.join(sources)
global output
output += f'build {target}: gen_run {script} {sources}\n'
output += f' options = {options}\n'
output += f' script = {script}\n'
output += f' infiles = {sources}\n'
return target
def OneShot(target, source, command, pool=None):
global output
output += f'build {target}: oneshot {source}\n'
output += f' command = {command}\n'
if pool:
output += f' pool = {pool}\n'
return target
def ForthTest(target, forth, test, interp='', pool=None):
global output
output += f'build {target}: forth_test {forth} {test}\n'
output += f' forth = {forth}\n'
output += f' test = {test}\n'
output += f' interp = {interp}\n'
if pool:
output += f' pool = {pool}\n'
return target
def Command(target, source, command, implicit=[], pool=None):
global output
implicit = ' '.join(implicit)
output += f'build {target}: cmd {source} | {implicit}\n'
output += f' cmd = {command}\n'
if pool:
output += f' pool = {pool}\n'
return target
def TestCommand(*args, **kwargs):
return Command(*args, **kwargs)
def Publish(target, source, pubpath):
global output
implicit = ' '.join([
'$src/tools/publish.py',
'$dst/gen/REVISION',
'$dst/gen/REVSHORT',
])
output += f'build {target}: publish {source} | {implicit}\n'
output += f' pubpath = {pubpath}\n'
return target
def Default(target):
global defaults
defaults.append(target)
return target
class SkipFileException(Exception):
pass
def Return():
raise SkipFileException()
def Include(path):
build_files.append(os.path.join('$src', path, 'BUILD'))
path = os.path.join(ROOT_DIR, path, 'BUILD')
data = open(path).read()
try:
exec(data)
except SkipFileException:
pass
except Exception as e:
sys.stderr.write('Failure in: ' + path + '\n')
raise e
def Main():
parser = argparse.ArgumentParser(
prog='configure',
description='Generate ninja.build')
parser.add_argument('-q', '--quiet', action='store_true')
parser.add_argument('-f', '--fast', action='store_true')
args = parser.parse_args()
global FAST
FAST = args.fast
DetectGenericTools(args)
DetectWindowsTools(args)
InitOutput()
Include('.')
header = SelectHeader()
with open('build.ninja', 'w') as fh:
fh.write(header)
fh.write(output)
fh.write(f'build all: phony ' + ' '.join(defaults) + '\n')
fh.write('default all\n')
fh.write(f'build $ninjadir/build.ninja: config $src/configure.py ' + ' '.join(build_files) + '\n')
if not args.quiet:
print('TO BUILD RUN: ninja')
if __name__ == '__main__':
Main()

160
esp32/BUILD Normal file
View File

@ -0,0 +1,160 @@
# Copyright 2023 Bradley D. Nelson
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
OPTIONS = '-I $src/esp32'
ESP32_FILES = []
ESP32_ZIP_FILES = []
ESP32_OPTIONAL = []
# Main files.
ESP32_ZIP_FILES += [
Importation('$dst/esp32/ESP32forth/README.txt',
'$src/esp32/README.txt'),
Importation('$dst/esp32/ESP32forth/ESP32forth.ino',
'$src/esp32/ESP32forth.ino',
implicit=['$dst/gen/esp32_boot.h'], keep=True, options=OPTIONS),
]
Importation('$dst/gen/esp32_boot.h', '$src/esp32/esp32_boot.fs', name='boot')
# Create a second copy of ESP32 where options will all be installed.
ESP32_OPTIONAL.append(
Copy('$dst/esp32/with_optional/ESP32forth/ESP32forth.ino',
'$dst/esp32/ESP32forth/ESP32forth.ino'))
def Esp32Optional(main_name, main_source, parts, very_optional=False):
global ESP32_OPTIONAL
if not very_optional:
ESP32_OPTIONAL.append(
Copy('$dst/esp32/with_optional/ESP32forth/' + main_name + '.h',
'$dst/esp32/ESP32forth/optional/' + main_name + '.h'))
implicit = []
for name, source in parts:
implicit.append(Importation('$dst/gen/esp32_' + name + '.h',
source, name=name.replace('-', '_') + '_source'))
return Importation('$dst/esp32/ESP32forth/optional/' + main_name + '.h',
main_source,
keep=True,
deps='$dst/gen/esp32_optional_' + main_name + '.h.d',
implicit=implicit)
# Optional Compontents.
ESP32_ZIP_FILES += [
Importation('$dst/esp32/ESP32forth/optional/README-optional.txt',
'$src/esp32/optional/README-optional.txt'),
Esp32Optional('rmt', '$src/esp32/optional/rmt.h', []),
Esp32Optional('assemblers', '$src/esp32/optional/assemblers/assemblers.h',
[('assembler', '$src/common/assembler.fs'),
('xtensa-assembler', '$src/esp32/optional/assemblers/xtensa-assembler.fs'),
('riscv-assembler', '$src/esp32/optional/assemblers/riscv-assembler.fs')]),
Esp32Optional('camera', '$src/esp32/optional/camera/camera.h',
[('camera', '$src/esp32/optional/camera/camera_server.fs')]),
Esp32Optional('interrupts', '$src/esp32/optional/interrupts/interrupts.h',
[('interrupts', '$src/esp32/optional/interrupts/timers.fs')]),
Esp32Optional('oled', '$src/esp32/optional/oled/oled.h',
[('oled', '$src/esp32/optional/oled/oled.fs')]),
Esp32Optional('serial-bluetooth', '$src/esp32/optional/serial-bluetooth/serial-bluetooth.h',
[('serial-bluetooth', '$src/esp32/optional/serial-bluetooth/serial-bluetooth.fs')],
very_optional=True),
Esp32Optional('http-client', '$src/esp32/optional/http-client/http-client.h', []),
Esp32Optional('spi-flash', '$src/esp32/optional/spi-flash/spi-flash.h',
[('spi-flash', '$src/esp32/optional/spi-flash/spi-flash.fs')], very_optional=True),
]
# Zip it.
ESP32_FILES += [
Zip('$dst/esp32/ESP32forth.zip', ESP32_ZIP_FILES, base='$dst/esp32/ESP32forth'),
]
# Simulator.
ESP32_FILES += [
Compile('$dst/esp32-sim/Esp32forth-sim', '$src/esp32/sim_main.cpp',
implicit=['$dst/gen/esp32_boot.h', '$dst/gen/esp32_sim_opcodes.h']),
TestCommand('$dst/esp32-sim/sizes.txt',
' '.join(['$dst/esp32-sim/Esp32forth-sim', '$src/tools/memuse.py']),
'echo internals size-all bye | $dst/esp32-sim/Esp32forth-sim | '
'$src/tools/memuse.py >$dst/esp32-sim/sizes.txt'),
ForthTest('$dst/tests/esp32_sim_all_tests.out',
'$dst/esp32-sim/Esp32forth-sim', '$src/esp32/esp32_all_tests.fs',
interp=('echo "include $src/esp32/esp32_all_tests.fs \\n1 terminate" | '
'$dst/esp32-sim/Esp32forth-sim')),
TestCommand('$dst/tests/esp32_sim_see_all_test.out',
'$dst/esp32-sim/Esp32forth-sim',
'echo internals see-all bye | $dst/esp32-sim/Esp32forth-sim '
'>$dst/tests/esp32_sim_see_all_test.out 2>&1'),
]
Compile('$dst/gen/print-esp32-builtins', '$src/esp32/print-builtins.cpp'),
Run('$dst/gen/esp32_sim_opcodes.h', '$dst/gen/print-esp32-builtins')
# Main Alias.
Alias('esp32', ' '.join(ESP32_FILES + ESP32_OPTIONAL))
Default('esp32')
# Automate building / flashing.
BOARDS = {
'esp32': '--fqbn=esp32:esp32:esp32:PSRAM=disabled,PartitionScheme=no_ota,CPUFreq=240,FlashMode=qio,FlashFreq=80,FlashSize=4M,UploadSpeed=921600,LoopCore=1,EventsCore=1,EraseFlash=none',
'esp32s2': '--fqbn=esp32:esp32:esp32s2:CDCOnBoot=default,MSCOnBoot=default,DFUOnBoot=default,UploadMode=default,PSRAM=disabled,PartitionScheme=default,CPUFreq=240,FlashMode=qio,FlashFreq=80,FlashSize=4M,UploadSpeed=921600,EraseFlash=none',
'esp32s3': '--fqbn=esp32:esp32:esp32s3:PSRAM=disabled,FlashMode=qio,FlashSize=4M,LoopCore=1,EventsCore=1,USBMode=hwcdc,CDCOnBoot=default,MSCOnBoot=default,DFUOnBoot=default,UploadMode=default,PartitionScheme=default,CPUFreq=240,UploadSpeed=921600,EraseFlash=none',
'esp32c3': '--fqbn=esp32:esp32:esp32c3:CDCOnBoot=default,PartitionScheme=default,CPUFreq=160,FlashMode=qio,FlashFreq=80,FlashSize=4M,UploadSpeed=921600,EraseFlash=none',
'esp32cam': '--fqbn=esp32:esp32:esp32cam:CPUFreq=240,FlashMode=qio,PartitionScheme=huge_app,FlashFreq=80,EraseFlash=none',
'tdongles3': '--fqbn=esp32:esp32:esp32s3:CDCOnBoot=cdc,FlashSize=16M,PartitionScheme=huge_app',
}
for board_base in BOARDS:
for optional, optional_dir, deps in (('', '', ESP32_FILES),
('opt', 'with_optional/', ESP32_OPTIONAL)):
options = BOARDS[board_base]
if optional:
options = options.replace('PartitionScheme=default', 'PartitionScheme=huge_app')
options = options.replace('PartitionScheme=no_ota', 'PartitionScheme=huge_app')
options += ',DebugLevel=$${DEBUG_LEVEL:-none}'
board = board_base + optional
clobber = f'rm -rf {WINTMP}/ueforth_esp32/{board}_dir/ && '
setup = (f'mkdir -p {WINTMP}/ueforth_esp32/{board}_dir/build && '
f'mkdir -p {WINTMP}/ueforth_esp32/{board}_dir/cache && '
f'cp -r $dst/esp32/' + optional_dir + f'ESP32forth/ {WINTMP}/ueforth_esp32/{board}_dir/ && '
f'cd {WINTMP} && ')
cmd = f' {ARDUINO_CLI} compile '
upload = '--port $${PORT:-com3} --upload '
args = (f'{options} '
f'--build-path ueforth_esp32/{board}_dir/build '
f'--build-cache-path ueforth_esp32/{board}_dir/cache '
f'ueforth_esp32/{board}_dir/ESP32forth/ESP32forth.ino ')
pipe = f' > ueforth_esp32/{board}_dir/build/build.out 2>&1 && '
copyout = (f'cd - && '
f'cp {WINTMP}/ueforth_esp32/{board}_dir/build/*.bin '
f'$dst/esp32/{board}_build/ && '
f'cp {WINTMP}/ueforth_esp32/{board}_dir/build/build.out '
f'$dst/esp32/{board}_build/build.out')
Shortcut(f'{board}-flash',
' '.join(deps),
setup + cmd + upload + args, pool='console')
Command(' '.join([f'$dst/esp32/{board}_build/ESP32forth.ino.bin',
f'$dst/esp32/{board}_build/build.out']),
' '.join(deps),
clobber + setup + cmd + args + pipe + copyout, pool='serial')
Alias(f'{board}-build', f'$dst/esp32/{board}_build/ESP32forth.ino.bin')
Alias('esp32all', ' '.join([i + '-build' for i in BOARDS.keys()]))
Alias('vet', ' '.join([
'all',
'esp32all',
'esp32opt-build',
]))
Shortcut('clobber-esp32', '', f'rm -rf {WINTMP}/ueforth_esp32/')
Shortcut('putty', '', '$${HOME}/Desktop/putty.exe -serial $${PORT:-com3} -sercfg 115200')

View File

@ -19,12 +19,14 @@
* Revision: {{REVISION}}
*/
{{options}}
{{tier0_opcodes}}
{{tier1_opcodes}}
{{tier2_opcodes}}
{{floats}}
{{calling}}
{{builtins.h}}
{{builtins.cpp}}
{{main.cpp}}
#include "esp32/platform.h"
#include "esp32/options.h"
#include "common/tier0_opcodes.h"
#include "common/tier1_opcodes.h"
#include "common/tier2_opcodes.h"
#include "common/floats.h"
#include "common/calls.h"
#include "common/bits.h"
#include "esp32/builtins.h"
#include "esp32/builtins.cpp"
#include "esp32/main.cpp"

20
esp32/README.txt Normal file
View File

@ -0,0 +1,20 @@
+--------------+
| ESP32forth |
+--------------+
This is ESP32forth v{{VERSION}} (Revision {{REVISION}}).
ESP32forth is an indirect threaded Forth for the ESP32 family of microcontrollers.
It uses a small C "kernel" that boots via inline Forth code.
The use of C allows developers to leverage C/C++ ESP32 libraries with minimal effort.
To compile and flash with the Arduino tools, load ESP32forth.ino.
Documentation and the latest version of ESP32forth are available at:
https://esp32forth.appspot.com/
Full unexpanded source code and an issue tracker are available at:
https://github.com/flagxor/ueforth
There are several optional components that you can add into ESP32forth.
See: optional/README-optional.txt

View File

@ -16,4 +16,3 @@
: allocate ( n -- a ior ) malloc dup 0= ;
: free ( a -- ior ) sysfree 0 ;
: resize ( a n -- a ior ) realloc dup 0= ;

View File

@ -25,8 +25,10 @@ internals definitions
( Check for autoexec.fs and run if present.
Failing that, try to revive save image. )
: autoexec
300 for key? if rdrop exit then 10 ms next
s" /spiffs/autoexec.fs" ['] included catch 2drop drop
( Allow skip start files if key hit within 100 ms )
10 for key? if rdrop exit then 10 ms next
s" /spiffs/autoexec.fs" 2dup file-exists?
if included else 2drop then
['] revive catch drop ;
' autoexec ( leave on the stack for fini.fs )

View File

@ -14,12 +14,14 @@
( Migrate various words to separate vocabularies, and constants )
forth definitions internals
: read-dir ( dh -- a n ) readdir dup if z>s else 0 then ;
forth definitions
vocabulary ESP ESP definitions
transfer ESP-builtins
only forth definitions
forth definitions
vocabulary Wire Wire definitions
transfer wire-builtins
forth definitions
@ -41,38 +43,6 @@ vocabulary SD_MMC SD_MMC definitions
transfer SD_MMC-builtins
forth definitions
vocabulary spi_flash spi_flash definitions
transfer spi_flash-builtins
DEFINED? spi_flash_init [IF]
0 constant SPI_PARTITION_TYPE_APP
1 constant SPI_PARTITION_TYPE_DATA
$ff constant SPI_PARTITION_SUBTYPE_ANY
also structures
struct esp_partition_t
( Work around changing struct layout )
esp_partition_t_size 40 >= [IF]
ptr field p>gap
[THEN]
ptr field p>type
ptr field p>subtype
ptr field p>address
ptr field p>size
ptr field p>label
: p. ( part -- )
base @ >r >r decimal
." TYPE: " r@ p>type @ . ." SUBTYPE: " r@ p>subtype @ .
." ADDR: " r@ hex p>address @ . ." SIZE: " r@ p>size @ .
." LABEL: " r> p>label @ z>s type cr r> base ! ;
: list-partition-type ( type -- )
SPI_PARTITION_SUBTYPE_ANY 0 esp_partition_find
begin dup esp_partition_get p. esp_partition_next dup 0= until drop ;
: list-partitions SPI_PARTITION_TYPE_APP list-partition-type
SPI_PARTITION_TYPE_DATA list-partition-type ;
[THEN]
only forth definitions
vocabulary SPIFFS SPIFFS definitions
transfer SPIFFS-builtins
forth definitions
@ -88,90 +58,41 @@ forth definitions
vocabulary sockets sockets definitions
transfer sockets-builtins
1 constant SOCK_STREAM
2 constant SOCK_DGRAM
3 constant SOCK_RAW
2 constant AF_INET
16 constant sizeof(sockaddr_in)
1 constant SOL_SOCKET
2 constant SO_REUSEADDR
: bs, ( n -- ) dup 256 / c, c, ;
: s, ( n -- ) dup c, 256 / c, ;
: l, ( n -- ) dup s, 65536 / s, ;
: bs, ( n -- ) dup 8 rshift c, c, ;
: s, ( n -- ) dup c, 8 rshift c, ;
: l, ( n -- ) dup s, 16 rshift s, ;
: sockaddr create 16 c, AF_INET c, 0 bs, 0 l, 0 l, 0 l, ;
: ->port@ ( a -- n ) 2 + >r r@ c@ 256 * r> 1+ c@ + ;
: ->port! ( n a -- ) 2 + >r dup 256 / r@ c! r> 1+ c! ;
forth definitions
vocabulary interrupts interrupts definitions
transfer interrupts-builtins
DEFINED? gpio_config [IF]
0 constant ESP_INTR_FLAG_DEFAULT
: ESP_INTR_FLAG_LEVELn ( n=1-6 -- n ) 1 swap lshift ;
1 7 lshift constant ESP_INTR_FLAG_NMI
1 8 lshift constant ESP_INTR_FLAG_SHARED
1 9 lshift constant ESP_INTR_FLAG_EDGE
1 10 lshift constant ESP_INTR_FLAG_IRAM
1 11 lshift constant ESP_INTR_FLAG_INTRDISABLED
( Prefix these with # because GPIO_INTR_DISABLE conflicts with a function. )
0 constant #GPIO_INTR_DISABLE
1 constant #GPIO_INTR_POSEDGE
2 constant #GPIO_INTR_NEGEDGE
3 constant #GPIO_INTR_ANYEDGE
4 constant #GPIO_INTR_LOW_LEVEL
5 constant #GPIO_INTR_HIGH_LEVEL
( Easy word to trigger on any change to a pin )
ESP_INTR_FLAG_DEFAULT gpio_install_isr_service drop
: pinchange ( xt pin ) dup #GPIO_INTR_ANYEDGE gpio_set_intr_type throw
swap 0 gpio_isr_handler_add throw ;
[THEN]
forth definitions
vocabulary rmt rmt definitions
transfer rmt-builtins
: ->port@ ( a -- n ) 2 + >r r@ c@ 8 lshift r> 1+ c@ + ;
: ->port! ( n a -- ) 2 + >r dup 8 rshift r@ c! r> 1+ c! ;
: ->addr@ ( a -- n ) 4 + ul@ ;
: ->addr! ( n a -- ) 4 + l! ;
: ->h_addr ( hostent -- n ) 2 cells + 8 + @ @ ul@ ;
: ip# ( n -- n ) dup 255 and n. [char] . emit 8 rshift ;
: ip. ( n -- ) ip# ip# ip# 255 and n. ;
forth definitions
vocabulary rtos rtos definitions
transfer rtos-builtins
forth definitions
vocabulary bluetooth bluetooth definitions
transfer bluetooth-builtins
forth definitions
vocabulary oled oled definitions
transfer oled-builtins
DEFINED? OledNew [IF]
128 constant WIDTH
64 constant HEIGHT
-1 constant OledReset
0 constant BLACK
1 constant WHITE
1 constant SSD1306_EXTERNALVCC
2 constant SSD1306_SWITCHCAPVCC
: OledInit
OledAddr @ 0= if
WIDTH HEIGHT OledReset OledNew
SSD1306_SWITCHCAPVCC $3C OledBegin drop
then
OledCLS
2 OledTextsize ( Draw 2x Scale Text )
WHITE OledTextc ( Draw white text )
0 0 OledSetCursor ( Start at top-left corner )
z" *Esp32forth*" OledPrintln OledDisplay
;
[THEN]
forth definitions
internals definitions
( Heap Capabilities )
binary
0001 constant MALLOC_CAP_EXEC
0010 constant MALLOC_CAP_32BIT
0100 constant MALLOC_CAP_8BIT
1000 constant MALLOC_CAP_DMA
: MALLOC_CAP_PID ( n -- ) 10000 over 11 ( 3 ) - for 2* next ;
000010000000000 constant MALLOC_CAP_SPIRAM
000100000000000 constant MALLOC_CAP_INTERNAL
001000000000000 constant MALLOC_CAP_DEFAULT
010000000000000 constant MALLOC_CAP_IRAM_8BIT
010000000000000 constant MALLOC_CAP_RETENTION
decimal
1 0 lshift constant MALLOC_CAP_EXEC
1 1 lshift constant MALLOC_CAP_32BIT
1 2 lshift constant MALLOC_CAP_8BIT
1 3 lshift constant MALLOC_CAP_DMA
1 10 lshift constant MALLOC_CAP_SPIRAM
1 11 lshift constant MALLOC_CAP_INTERNAL
1 12 lshift constant MALLOC_CAP_DEFAULT
1 13 lshift constant MALLOC_CAP_IRAM_8BIT
1 14 lshift constant MALLOC_CAP_RETENTION
1 15 lshift constant MALLOC_CAP_RTCRAM
forth definitions

View File

@ -13,11 +13,13 @@
// limitations under the License.
static char filename[PATH_MAX];
static char filename2[PATH_MAX];
{{bits}}
{{core}}
{{interp}}
{{boot}}
#include "common/core.h"
#include "esp32/faults.h"
#include "common/calling.h"
#include "common/interp.h"
#include "gen/esp32_boot.h"
// Work around lack of ftruncate
static cell_t ResizeFile(cell_t fd, cell_t size) {
@ -49,50 +51,3 @@ static cell_t ResizeFile(cell_t fd, cell_t size) {
if (t < 0) { return errno; }
return 0;
}
#ifdef ENABLE_INTERRUPTS_SUPPORT
struct handle_interrupt_args {
cell_t xt;
cell_t arg;
};
static void IRAM_ATTR HandleInterrupt(void *arg) {
struct handle_interrupt_args *args = (struct handle_interrupt_args *) arg;
cell_t code[2];
code[0] = args->xt;
code[1] = g_sys->YIELD_XT;
cell_t fstack[INTERRUPT_STACK_CELLS];
cell_t rstack[INTERRUPT_STACK_CELLS];
cell_t stack[INTERRUPT_STACK_CELLS];
stack[0] = args->arg;
cell_t *rp = rstack;
*++rp = (cell_t) (fstack + 1);
*++rp = (cell_t) (stack + 1);
*++rp = (cell_t) code;
forth_run(rp);
}
static cell_t EspIntrAlloc(cell_t source, cell_t flags, cell_t xt, cell_t arg, void *ret) {
// NOTE: Leaks memory.
struct handle_interrupt_args *args = (struct handle_interrupt_args *) malloc(sizeof(struct handle_interrupt_args));
args->xt = xt;
args->arg = arg;
return esp_intr_alloc(source, flags, HandleInterrupt, args, (intr_handle_t *) ret);
}
static cell_t GpioIsrHandlerAdd(cell_t pin, cell_t xt, cell_t arg) {
// NOTE: Leaks memory.
struct handle_interrupt_args *args = (struct handle_interrupt_args *) malloc(sizeof(struct handle_interrupt_args));
args->xt = xt;
args->arg = arg;
return gpio_isr_handler_add((gpio_num_t) pin, HandleInterrupt, args);
}
static cell_t TimerIsrRegister(cell_t group, cell_t timer, cell_t xt, cell_t arg, cell_t flags, void *ret) {
// NOTE: Leaks memory.
struct handle_interrupt_args *args = (struct handle_interrupt_args *) malloc(sizeof(struct handle_interrupt_args));
args->xt = xt;
args->arg = arg;
return timer_isr_register((timer_group_t) group, (timer_idx_t) timer, HandleInterrupt, args, flags, (timer_isr_handle_t *) ret);
}
#endif

View File

@ -14,6 +14,7 @@
#ifndef SIM_PRINT_ONLY
# include <dirent.h>
# include <errno.h>
# include <unistd.h>
# include <fcntl.h>
@ -21,26 +22,93 @@
# include <sys/stat.h>
# include <sys/select.h>
// Optional hook to pull in words for userwords.h
// Hook to pull in words from optional userwords.h
# if __has_include("userwords.h")
# include "userwords.h"
# else
# define USER_WORDS
# endif
// Hook to pull in words from optional assemblers.
# if __has_include("assemblers.h")
# include "assemblers.h"
# else
# define OPTIONAL_ASSEMBLERS_SUPPORT
# endif
// Hook to pull in optional interrupts and timers support.
# if __has_include("interrupts.h")
# include "interrupts.h"
# else
# define OPTIONAL_INTERRUPTS_VOCABULARIES
# define OPTIONAL_INTERRUPTS_SUPPORT
# endif
// Hook to pull in optional Oled support.
# if __has_include("oled.h")
# include "oled.h"
# else
# define OPTIONAL_OLED_VOCABULARY
# define OPTIONAL_OLED_SUPPORT
# endif
// Hook to pull in optional ESP32-CAM camera support.
# if __has_include("camera.h")
# include "camera.h"
# else
# define OPTIONAL_CAMERA_VOCABULARY
# define OPTIONAL_CAMERA_SUPPORT
# endif
// Hook to pull in optional RMT (Remote Control) support.
# if __has_include("rmt.h")
# include "rmt.h"
# else
# define OPTIONAL_RMT_VOCABULARY
# define OPTIONAL_RMT_SUPPORT
# endif
// Hook to pull in optional serial bluetooth support.
# if __has_include("serial-bluetooth.h")
# include "serial-bluetooth.h"
# else
# define OPTIONAL_BLUETOOTH_VOCABULARY
# define OPTIONAL_SERIAL_BLUETOOTH_SUPPORT
# endif
// Hook to pull in optional SPI flash support.
# if __has_include("spi-flash.h")
# include "spi-flash.h"
# else
# define OPTIONAL_SPI_FLASH_VOCABULARY
# define OPTIONAL_SPI_FLASH_SUPPORT
# endif
// Hook to pull in optional HTTPClient support.
# if __has_include("http-client.h")
# include "http-client.h"
# else
# define OPTIONAL_HTTP_CLIENT_VOCABULARY
# define OPTIONAL_HTTP_CLIENT_SUPPORT
# endif
static cell_t ResizeFile(cell_t fd, cell_t size);
#endif
#define PLATFORM_OPCODE_LIST \
USER_WORDS \
EXTERNAL_OPTIONAL_MODULE_SUPPORT \
REQUIRED_PLATFORM_SUPPORT \
REQUIRED_ESP_SUPPORT \
REQUIRED_MEMORY_SUPPORT \
REQUIRED_SERIAL_SUPPORT \
OPTIONAL_SERIAL2_SUPPORT \
REQUIRED_ARDUINO_GPIO_SUPPORT \
REQUIRED_SYSTEM_SUPPORT \
REQUIRED_FILES_SUPPORT \
OPTIONAL_LEDC_SUPPORT \
OPTIONAL_LEDC_V2_SUPPORT \
OPTIONAL_LEDC_V3_SUPPORT \
OPTIONAL_DAC_SUPPORT \
OPTIONAL_SPIFFS_SUPPORT \
OPTIONAL_WIFI_SUPPORT \
@ -48,16 +116,21 @@ static cell_t ResizeFile(cell_t fd, cell_t size);
OPTIONAL_SD_SUPPORT \
OPTIONAL_SD_MMC_SUPPORT \
OPTIONAL_I2C_SUPPORT \
OPTIONAL_SERIAL_BLUETOOTH_SUPPORT \
OPTIONAL_CAMERA_SUPPORT \
OPTIONAL_SOCKETS_SUPPORT \
OPTIONAL_FREERTOS_SUPPORT \
OPTIONAL_INTERRUPTS_SUPPORT \
OPTIONAL_RMT_SUPPORT \
OPTIONAL_OLED_SUPPORT \
OPTIONAL_SPI_FLASH_SUPPORT \
CALLING_OPCODE_LIST \
FLOATING_POINT_LIST
#define EXTERNAL_OPTIONAL_MODULE_SUPPORT \
OPTIONAL_ASSEMBLERS_SUPPORT \
OPTIONAL_CAMERA_SUPPORT \
OPTIONAL_INTERRUPTS_SUPPORT \
OPTIONAL_OLED_SUPPORT \
OPTIONAL_RMT_SUPPORT \
OPTIONAL_SERIAL_BLUETOOTH_SUPPORT \
OPTIONAL_SPI_FLASH_SUPPORT \
OPTIONAL_HTTP_CLIENT_SUPPORT
#define REQUIRED_MEMORY_SUPPORT \
YV(internals, MALLOC, SET malloc(n0)) \
YV(internals, SYSFREE, free(a0); DROP) \
@ -65,7 +138,22 @@ static cell_t ResizeFile(cell_t fd, cell_t size);
YV(internals, heap_caps_malloc, SET heap_caps_malloc(n1, n0); NIP) \
YV(internals, heap_caps_free, heap_caps_free(a0); DROP) \
YV(internals, heap_caps_realloc, \
tos = (cell_t) heap_caps_realloc(a2, n1, n0); NIPn(2))
tos = (cell_t) heap_caps_realloc(a2, n1, n0); NIPn(2)) \
YV(internals, heap_caps_get_total_size, n0 = heap_caps_get_total_size(n0)) \
YV(internals, heap_caps_get_free_size, n0 = heap_caps_get_free_size(n0)) \
YV(internals, heap_caps_get_minimum_free_size, \
n0 = heap_caps_get_minimum_free_size(n0)) \
YV(internals, heap_caps_get_largest_free_block, \
n0 = heap_caps_get_largest_free_block(n0))
#define REQUIRED_PLATFORM_SUPPORT \
X("ESP32?", IS_ESP32, PUSH UEFORTH_PLATFORM_IS_ESP32) \
X("ESP32-S2?", IS_ESP32S2, PUSH UEFORTH_PLATFORM_IS_ESP32S2) \
X("ESP32-S3?", IS_ESP32S3, PUSH UEFORTH_PLATFORM_IS_ESP32S3) \
X("ESP32-C3?", IS_ESP32C3, PUSH UEFORTH_PLATFORM_IS_ESP32C3) \
X("PSRAM?", HAS_PSRAM, PUSH UEFORTH_PLATFORM_HAS_PSRAM) \
X("Xtensa?", IS_XTENSA, PUSH UEFORTH_PLATFORM_IS_XTENSA) \
X("RISC-V?", IS_RISCV, PUSH UEFORTH_PLATFORM_IS_RISCV)
#define REQUIRED_ESP_SUPPORT \
YV(ESP, getHeapSize, PUSH ESP.getHeapSize()) \
@ -76,26 +164,40 @@ static cell_t ResizeFile(cell_t fd, cell_t size);
YV(ESP, getFlashChipSize, PUSH ESP.getFlashChipSize()) \
YV(ESP, getCpuFreqMHz, PUSH ESP.getCpuFreqMHz()) \
YV(ESP, getSketchSize, PUSH ESP.getSketchSize()) \
YV(ESP, deepSleep, ESP.deepSleep(tos); DROP)
YV(ESP, deepSleep, ESP.deepSleep(tos); DROP) \
YV(ESP, getEfuseMac, PUSH (cell_t) ESP.getEfuseMac(); PUSH (cell_t) (ESP.getEfuseMac() >> 32)) \
YV(ESP, esp_log_level_set, esp_log_level_set(c1, (esp_log_level_t) n0); DROPn(2))
#define REQUIRED_SYSTEM_SUPPORT \
X("MS-TICKS", MS_TICKS, PUSH millis()) \
XV(internals, "RAW-YIELD", RAW_YIELD, yield()) \
Y(TERMINATE, exit(n0))
XV(internals, "RAW-TERMINATE", RAW_TERMINATE, ESP.restart())
#define REQUIRED_SERIAL_SUPPORT \
XV(serial, "Serial.begin", SERIAL_BEGIN, Serial.begin(tos); DROP) \
XV(serial, "Serial.begin3", SERIAL_BEGIN3, Serial.begin(n2, SERIAL_8N1, n1, n0); DROPn(3)) \
XV(serial, "Serial.end", SERIAL_END, Serial.end()) \
XV(serial, "Serial.available", SERIAL_AVAILABLE, PUSH Serial.available()) \
XV(serial, "Serial.readBytes", SERIAL_READ_BYTES, n0 = Serial.readBytes(b1, n0); NIP) \
XV(serial, "Serial.write", SERIAL_WRITE, n0 = Serial.write(b1, n0); NIP) \
XV(serial, "Serial.writeChar", SERIAL_WRITECHAR, n0 = Serial.write(n0)) \
XV(serial, "Serial.flush", SERIAL_FLUSH, Serial.flush()) \
XV(serial, "Serial.setDebugOutput", SERIAL_DEBUG_OUTPUT, Serial.setDebugOutput(n0); DROP)
#ifndef ENABLE_SERIAL2_SUPPORT
# define OPTIONAL_SERIAL2_SUPPORT
#else
# define OPTIONAL_SERIAL2_SUPPORT \
XV(serial, "Serial2.begin", SERIAL2_BEGIN, Serial2.begin(tos); DROP) \
XV(serial, "Serial2.begin3", SERIAL2_BEGIN3, Serial2.begin(n2, SERIAL_8N1, n1, n0); DROPn(3)) \
XV(serial, "Serial2.end", SERIAL2_END, Serial2.end()) \
XV(serial, "Serial2.available", SERIAL2_AVAILABLE, PUSH Serial2.available()) \
XV(serial, "Serial2.readBytes", SERIAL2_READ_BYTES, n0 = Serial2.readBytes(b1, n0); NIP) \
XV(serial, "Serial2.write", SERIAL2_WRITE, n0 = Serial2.write(b1, n0); NIP) \
XV(serial, "Serial2.flush", SERIAL2_FLUSH, Serial2.flush())
XV(serial, "Serial2.writeChar", SERIAL2_WRITECHAR, n0 = Serial2.write(n0)) \
XV(serial, "Serial2.flush", SERIAL2_FLUSH, Serial2.flush()) \
XV(serial, "Serial2.setDebugOutput", SERIAL2_DEBUG_OUTPUT, Serial2.setDebugOutput(n0); DROP)
#endif
#define REQUIRED_ARDUINO_GPIO_SUPPORT \
Y(pinMode, pinMode(n1, n0); DROPn(2)) \
@ -120,7 +222,10 @@ static cell_t ResizeFile(cell_t fd, cell_t size);
X("DELETE-FILE", DELETE_FILE, cell_t len = n0; DROP; \
memcpy(filename, a0, len); filename[len] = 0; \
n0 = unlink(filename); n0 = n0 ? errno : 0) \
X("RENAME-FILE", RENAME_FILE, NIPn(3); /* unimplemented */ n0 = 1) \
X("RENAME-FILE", RENAME_FILE, \
cell_t len = n0; DROP; memcpy(filename, a0, len); filename[len] = 0; DROP; \
cell_t len2 = n0; DROP; memcpy(filename2, a0, len2); filename2[len2] = 0; \
n0 = rename(filename2, filename); n0 = n0 ? errno : 0) \
X("WRITE-FILE", WRITE_FILE, cell_t fd = n0; DROP; cell_t len = n0; DROP; \
n0 = write(fd, a0, len); n0 = n0 != len ? errno : 0) \
X("READ-FILE", READ_FILE, cell_t fd = n0; DROP; cell_t len = n0; DROP; \
@ -133,12 +238,17 @@ static cell_t ResizeFile(cell_t fd, cell_t size);
X("FILE-SIZE", FILE_SIZE, struct stat st; w = fstat(n0, &st); \
n0 = (cell_t) st.st_size; PUSH w < 0 ? errno : 0) \
X("NON-BLOCK", NON_BLOCK, n0 = fcntl(n0, F_SETFL, O_NONBLOCK); \
n0 = n0 < 0 ? errno : 0)
n0 = n0 < 0 ? errno : 0) \
X("OPEN-DIR", OPEN_DIR, memcpy(filename, a1, n0); filename[n0] = 0; \
n1 = (cell_t) opendir(filename); n0 = n1 ? 0 : errno) \
X("CLOSE-DIR", CLOSE_DIR, n0 = closedir((DIR *) n0); n0 = n0 ? errno : 0) \
YV(internals, READDIR, \
struct dirent *ent = readdir((DIR *) n0); SET (ent ? ent->d_name: 0))
#ifndef ENABLE_LEDC_SUPPORT
# define OPTIONAL_LEDC_SUPPORT
#ifndef ENABLE_LEDC_V2_SUPPORT
# define OPTIONAL_LEDC_V2_SUPPORT
#else
# define OPTIONAL_LEDC_SUPPORT \
# define OPTIONAL_LEDC_V2_SUPPORT \
YV(ledc, ledcSetup, \
n0 = (cell_t) (1000000 * ledcSetup(n2, n1 / 1000.0, n0)); NIPn(2)) \
YV(ledc, ledcAttachPin, ledcAttachPin(n1, n0); DROPn(2)) \
@ -152,6 +262,21 @@ static cell_t ResizeFile(cell_t fd, cell_t size);
tos = (cell_t) (1000000 * ledcWriteNote(n2, (note_t) n1, n0)); NIPn(2))
#endif
#ifndef ENABLE_LEDC_V3_SUPPORT
# define OPTIONAL_LEDC_V3_SUPPORT
#else
# define OPTIONAL_LEDC_V3_SUPPORT \
YV(ledc, ledcAttach, n0 = ledcAttach(n2, n1, n0); NIPn(2)) \
YV(ledc, ledcAttachChannel, n0 = ledcAttachChannel(n3, n2, n1, n0); NIPn(3)) \
YV(ledc, ledcDetach, n0 = ledcDetach(n0)) \
YV(ledc, ledcRead, n0 = ledcRead(n0)) \
YV(ledc, ledcReadFreq, n0 = ledcReadFreq(n0)) \
YV(ledc, ledcWrite, ledcWrite(n1, n0); DROPn(2)) \
YV(ledc, ledcWriteTone, n0 = ledcWriteTone(n1, n0); NIP) \
YV(ledc, ledcWriteNote, n0 = ledcWriteNote(n2, (note_t) n1, n0); NIPn(2)) \
YV(ledc, ledcChangeFrequency, n0 = ledcChangeFrequency(n2, n1, n0); NIPn(2))
#endif
#ifndef ENABLE_DAC_SUPPORT
# define OPTIONAL_DAC_SUPPORT
# else
@ -159,68 +284,6 @@ static cell_t ResizeFile(cell_t fd, cell_t size);
Y(dacWrite, dacWrite(n1, n0); DROPn(2))
#endif
#ifndef ENABLE_SPI_FLASH_SUPPORT
# define OPTIONAL_SPI_FLASH_SUPPORT
#else
# ifndef SIM_PRINT_ONLY
# include "esp_spi_flash.h"
# include "esp_partition.h"
# endif
# define OPTIONAL_SPI_FLASH_SUPPORT \
YV(spi_flash, spi_flash_init, spi_flash_init()) \
YV(spi_flash, spi_flash_get_chip_size, PUSH spi_flash_get_chip_size()) \
YV(spi_flash, spi_flash_erase_sector, n0 = spi_flash_erase_sector(n0)) \
YV(spi_flash, spi_flash_erase_range, n0 = spi_flash_erase_range(n1, n0); DROP) \
YV(spi_flash, spi_flash_write, n0 = spi_flash_write(n2, a1, n0); NIPn(2)) \
YV(spi_flash, spi_flash_write_encrypted, n0 = spi_flash_write_encrypted(n2, a1, n0); NIPn(2)) \
YV(spi_flash, spi_flash_read, n0 = spi_flash_read(n2, a1, n0); NIPn(2)) \
YV(spi_flash, spi_flash_read_encrypted, n0 = spi_flash_read_encrypted(n2, a1, n0); NIPn(2)) \
YV(spi_flash, spi_flash_mmap, \
n0 = spi_flash_mmap(n4, n3, (spi_flash_mmap_memory_t) n2, \
(const void **) a1, (spi_flash_mmap_handle_t *) a0); NIPn(4)) \
YV(spi_flash, spi_flash_mmap_pages, \
n0 = spi_flash_mmap_pages((const int *) a4, n3, (spi_flash_mmap_memory_t) n2, \
(const void **) a1, (spi_flash_mmap_handle_t *) a0); NIPn(4)) \
YV(spi_flash, spi_flash_munmap, spi_flash_munmap((spi_flash_mmap_handle_t) a0); DROP) \
YV(spi_flash, spi_flash_mmap_dump, spi_flash_mmap_dump()) \
YV(spi_flash, spi_flash_mmap_get_free_pages, \
n0 = spi_flash_mmap_get_free_pages((spi_flash_mmap_memory_t) n0)) \
YV(spi_flash, spi_flash_cache2phys, n0 = spi_flash_cache2phys(a0)) \
YV(spi_flash, spi_flash_phys2cache, \
n0 = (cell_t) spi_flash_phys2cache(n1, (spi_flash_mmap_memory_t) n0); NIP) \
YV(spi_flash, spi_flash_cache_enabled, PUSH spi_flash_cache_enabled()) \
YV(spi_flash, esp_partition_find, \
n0 = (cell_t) esp_partition_find((esp_partition_type_t) n2, \
(esp_partition_subtype_t) n1, c0); NIPn(2)) \
YV(spi_flash, esp_partition_find_first, \
n0 = (cell_t) esp_partition_find_first((esp_partition_type_t) n2, \
(esp_partition_subtype_t) n1, c0); NIPn(2)) \
YV(spi_flash, esp_partition_t_size, PUSH sizeof(esp_partition_t)) \
YV(spi_flash, esp_partition_get, \
n0 = (cell_t) esp_partition_get((esp_partition_iterator_t) a0)) \
YV(spi_flash, esp_partition_next, \
n0 = (cell_t) esp_partition_next((esp_partition_iterator_t) a0)) \
YV(spi_flash, esp_partition_iterator_release, \
esp_partition_iterator_release((esp_partition_iterator_t) a0); DROP) \
YV(spi_flash, esp_partition_verify, n0 = (cell_t) esp_partition_verify((esp_partition_t *) a0)) \
YV(spi_flash, esp_partition_read, \
n0 = esp_partition_read((const esp_partition_t *) a3, n2, a1, n0); NIPn(3)) \
YV(spi_flash, esp_partition_write, \
n0 = esp_partition_write((const esp_partition_t *) a3, n2, a1, n0); NIPn(3)) \
YV(spi_flash, esp_partition_erase_range, \
n0 = esp_partition_erase_range((const esp_partition_t *) a2, n1, n0); NIPn(2)) \
YV(spi_flash, esp_partition_mmap, \
n0 = esp_partition_mmap((const esp_partition_t *) a5, n4, n3, \
(spi_flash_mmap_memory_t) n2, \
(const void **) a1, \
(spi_flash_mmap_handle_t *) a0); NIPn(5)) \
YV(spi_flash, esp_partition_get_sha256, \
n0 = esp_partition_get_sha256((const esp_partition_t *) a1, b0); NIP) \
YV(spi_flash, esp_partition_check_identity, \
n0 = esp_partition_check_identity((const esp_partition_t *) a1, \
(const esp_partition_t *) a0); NIP)
#endif
#ifndef ENABLE_SPIFFS_SUPPORT
// Provide a default failing SPIFFS.begin
# define OPTIONAL_SPIFFS_SUPPORT \
@ -235,7 +298,8 @@ static cell_t ResizeFile(cell_t fd, cell_t size);
XV(SPIFFS, "SPIFFS.end", SPIFFS_END, SPIFFS.end()) \
XV(SPIFFS, "SPIFFS.format", SPIFFS_FORMAT, PUSH SPIFFS.format()) \
XV(SPIFFS, "SPIFFS.totalBytes", SPIFFS_TOTAL_BYTES, PUSH SPIFFS.totalBytes()) \
XV(SPIFFS, "SPIFFS.usedBytes", SPIFFS_USED_BYTES, PUSH SPIFFS.usedBytes())
XV(SPIFFS, "SPIFFS.usedBytes", SPIFFS_USED_BYTES, PUSH SPIFFS.usedBytes()) \
XV(SPIFFS, "SPIFFS.exists", SPIFFS_EXISTS, n0 = SPIFFS.exists(c0) ? -1 : 0)
#endif
#ifndef ENABLE_FREERTOS_SUPPORT
@ -252,127 +316,12 @@ static cell_t ResizeFile(cell_t fd, cell_t size);
YV(rtos, xPortGetCoreID, PUSH xPortGetCoreID())
#endif
#ifndef ENABLE_INTERRUPTS_SUPPORT
# define OPTIONAL_INTERRUPTS_SUPPORT
#else
# ifndef SIM_PRINT_ONLY
# include "esp_intr_alloc.h"
# include "driver/timer.h"
# include "driver/gpio.h"
static cell_t EspIntrAlloc(cell_t source, cell_t flags, cell_t xt, cell_t arg, void *ret);
static cell_t GpioIsrHandlerAdd(cell_t pin, cell_t xt, cell_t arg);
static cell_t TimerIsrRegister(cell_t group, cell_t timer, cell_t xt, cell_t arg, cell_t flags, void *ret);
# endif
# define OPTIONAL_INTERRUPTS_SUPPORT \
YV(interrupts, gpio_config, n0 = gpio_config((const gpio_config_t *) a0)) \
YV(interrupts, gpio_reset_pin, n0 = gpio_reset_pin((gpio_num_t) n0)) \
YV(interrupts, gpio_set_intr_type, n0 = gpio_set_intr_type((gpio_num_t) n1, (gpio_int_type_t) n0); NIP) \
YV(interrupts, gpio_intr_enable, n0 = gpio_intr_enable((gpio_num_t) n0)) \
YV(interrupts, gpio_intr_disable, n0 = gpio_intr_disable((gpio_num_t) n0)) \
YV(interrupts, gpio_set_level, n0 = gpio_set_level((gpio_num_t) n1, n0); NIP) \
YV(interrupts, gpio_get_level, n0 = gpio_get_level((gpio_num_t) n0)) \
YV(interrupts, gpio_set_direction, n0 = gpio_set_direction((gpio_num_t) n1, (gpio_mode_t) n0); NIP) \
YV(interrupts, gpio_set_pull_mode, n0 = gpio_set_pull_mode((gpio_num_t) n1, (gpio_pull_mode_t) n0); NIP) \
YV(interrupts, gpio_wakeup_enable, n0 = gpio_wakeup_enable((gpio_num_t) n1, (gpio_int_type_t) n0); NIP) \
YV(interrupts, gpio_wakeup_disable, n0 = gpio_wakeup_disable((gpio_num_t) n0)) \
YV(interrupts, gpio_pullup_en, n0 = gpio_pullup_en((gpio_num_t) n0)) \
YV(interrupts, gpio_pullup_dis, n0 = gpio_pullup_dis((gpio_num_t) n0)) \
YV(interrupts, gpio_pulldown_en, n0 = gpio_pulldown_en((gpio_num_t) n0)) \
YV(interrupts, gpio_pulldown_dis, n0 = gpio_pulldown_dis((gpio_num_t) n0)) \
YV(interrupts, gpio_hold_en, n0 = gpio_hold_en((gpio_num_t) n0)) \
YV(interrupts, gpio_hold_dis, n0 = gpio_hold_dis((gpio_num_t) n0)) \
YV(interrupts, gpio_deep_sleep_hold_en, gpio_deep_sleep_hold_en()) \
YV(interrupts, gpio_deep_sleep_hold_dis, gpio_deep_sleep_hold_dis()) \
YV(interrupts, gpio_install_isr_service, n0 = gpio_install_isr_service(n0)) \
YV(interrupts, gpio_uninstall_isr_service, gpio_uninstall_isr_service()) \
YV(interrupts, gpio_isr_handler_add, n0 = GpioIsrHandlerAdd(n2, n1, n0); NIPn(2)) \
YV(interrupts, gpio_isr_handler_remove, n0 = gpio_isr_handler_remove((gpio_num_t) n0)) \
YV(interrupts, gpio_set_drive_capability, n0 = gpio_set_drive_capability((gpio_num_t) n1, (gpio_drive_cap_t) n0); NIP) \
YV(interrupts, gpio_get_drive_capability, n0 = gpio_get_drive_capability((gpio_num_t) n1, (gpio_drive_cap_t *) a0); NIP) \
YV(interrupts, esp_intr_alloc, n0 = EspIntrAlloc(n4, n3, n2, n1, a0); NIPn(4)) \
YV(interrupts, esp_intr_free, n0 = esp_intr_free((intr_handle_t) n0)) \
YV(timers, timer_isr_register, n0 = TimerIsrRegister(n5, n4, n3, n2, n1, a0); NIPn(5))
#endif
#ifndef ENABLE_RMT_SUPPORT
# define OPTIONAL_RMT_SUPPORT
#else
# ifndef SIM_PRINT_ONLY
# include "driver/rmt.h"
# endif
# define OPTIONAL_RMT_SUPPORT \
YV(rmt, rmt_set_clk_div, n0 = rmt_set_clk_div((rmt_channel_t) n1, n0); NIP) \
YV(rmt, rmt_get_clk_div, n0 = rmt_get_clk_div((rmt_channel_t) n1, b0); NIP) \
YV(rmt, rmt_set_rx_idle_thresh, n0 = rmt_set_rx_idle_thresh((rmt_channel_t) n1, n0); NIP) \
YV(rmt, rmt_get_rx_idle_thresh, \
n0 = rmt_get_rx_idle_thresh((rmt_channel_t) n1, (uint16_t *) a0); NIP) \
YV(rmt, rmt_set_mem_block_num, n0 = rmt_set_mem_block_num((rmt_channel_t) n1, n0); NIP) \
YV(rmt, rmt_get_mem_block_num, n0 = rmt_get_mem_block_num((rmt_channel_t) n1, b0); NIP) \
YV(rmt, rmt_set_tx_carrier, n0 = rmt_set_tx_carrier((rmt_channel_t) n4, n3, n2, n1, \
(rmt_carrier_level_t) n0); NIPn(4)) \
YV(rmt, rmt_set_mem_pd, n0 = rmt_set_mem_pd((rmt_channel_t) n1, n0); NIP) \
YV(rmt, rmt_get_mem_pd, n0 = rmt_get_mem_pd((rmt_channel_t) n1, (bool *) a0); NIP) \
YV(rmt, rmt_tx_start, n0 = rmt_tx_start((rmt_channel_t) n1, n0); NIP) \
YV(rmt, rmt_tx_stop, n0 = rmt_tx_stop((rmt_channel_t) n0)) \
YV(rmt, rmt_rx_start, n0 = rmt_rx_start((rmt_channel_t) n1, n0); NIP) \
YV(rmt, rmt_rx_stop, n0 = rmt_rx_stop((rmt_channel_t) n0)) \
YV(rmt, rmt_tx_memory_reset, n0 = rmt_tx_memory_reset((rmt_channel_t) n0)) \
YV(rmt, rmt_rx_memory_reset, n0 = rmt_rx_memory_reset((rmt_channel_t) n0)) \
YV(rmt, rmt_set_memory_owner, n0 = rmt_set_memory_owner((rmt_channel_t) n1, (rmt_mem_owner_t) n0); NIP) \
YV(rmt, rmt_get_memory_owner, n0 = rmt_get_memory_owner((rmt_channel_t) n1, (rmt_mem_owner_t *) a0); NIP) \
YV(rmt, rmt_set_tx_loop_mode, n0 = rmt_set_tx_loop_mode((rmt_channel_t) n1, n0); NIP) \
YV(rmt, rmt_get_tx_loop_mode, n0 = rmt_get_tx_loop_mode((rmt_channel_t) n1, (bool *) a0); NIP) \
YV(rmt, rmt_set_rx_filter, n0 = rmt_set_rx_filter((rmt_channel_t) n2, n1, n0); NIPn(2)) \
YV(rmt, rmt_set_source_clk, n0 = rmt_set_source_clk((rmt_channel_t) n1, (rmt_source_clk_t) n0); NIP) \
YV(rmt, rmt_get_source_clk, n0 = rmt_get_source_clk((rmt_channel_t) n1, (rmt_source_clk_t * ) a0); NIP) \
YV(rmt, rmt_set_idle_level, n0 = rmt_set_idle_level((rmt_channel_t) n2, n1, \
(rmt_idle_level_t) n0); NIPn(2)) \
YV(rmt, rmt_get_idle_level, n0 = rmt_get_idle_level((rmt_channel_t) n2, \
(bool *) a1, (rmt_idle_level_t *) a0); NIPn(2)) \
YV(rmt, rmt_get_status, n0 = rmt_get_status((rmt_channel_t) n1, (uint32_t *) a0); NIP) \
YV(rmt, rmt_set_rx_intr_en, n0 = rmt_set_rx_intr_en((rmt_channel_t) n1, n0); NIP) \
YV(rmt, rmt_set_err_intr_en, n0 = rmt_set_err_intr_en((rmt_channel_t) n1, (rmt_mode_t) n0); NIP) \
YV(rmt, rmt_set_tx_intr_en, n0 = rmt_set_tx_intr_en((rmt_channel_t) n1, n0); NIP) \
YV(rmt, rmt_set_tx_thr_intr_en, n0 = rmt_set_tx_thr_intr_en((rmt_channel_t) n2, n1, n0); NIPn(2)) \
YV(rmt, rmt_set_gpio, n0 = rmt_set_gpio((rmt_channel_t) n3, (rmt_mode_t) n2, (gpio_num_t) n1, n0); NIPn(3)) \
YV(rmt, rmt_config, n0 = rmt_config((const rmt_config_t *) a0)) \
YV(rmt, rmt_isr_register, n0 = rmt_isr_register((void (*)(void*)) a3, a2, n1, \
(rmt_isr_handle_t *) a0); NIPn(3)) \
YV(rmt, rmt_isr_deregister, n0 = rmt_isr_deregister((rmt_isr_handle_t) n0)) \
YV(rmt, rmt_fill_tx_items, n0 = rmt_fill_tx_items((rmt_channel_t) n3, \
(rmt_item32_t *) a2, n1, n0); NIPn(3)) \
YV(rmt, rmt_driver_install, n0 = rmt_driver_install((rmt_channel_t) n2, n1, n0); NIPn(2)) \
YV(rmt, rmt_driver_uinstall, n0 = rmt_driver_uninstall((rmt_channel_t) n0)) \
YV(rmt, rmt_get_channel_status, n0 = rmt_get_channel_status((rmt_channel_status_result_t *) a0)) \
YV(rmt, rmt_get_counter_clock, n0 = rmt_get_counter_clock((rmt_channel_t) n1, (uint32_t *) a0); NIP) \
YV(rmt, rmt_write_items, n0 = rmt_write_items((rmt_channel_t) n3, (rmt_item32_t *) a2, n1, n0); NIPn(3)) \
YV(rmt, rmt_wait_tx_done, n0 = rmt_wait_tx_done((rmt_channel_t) n1, n0); NIP) \
YV(rmt, rmt_get_ringbuf_handle, n0 = rmt_get_ringbuf_handle((rmt_channel_t) n1, (RingbufHandle_t *) a0); NIP) \
YV(rmt, rmt_translator_init, n0 = rmt_translator_init((rmt_channel_t) n1, (sample_to_rmt_t) n0); NIP) \
YV(rmt, rmt_translator_set_context, n0 = rmt_translator_set_context((rmt_channel_t) n1, a0); NIP) \
YV(rmt, rmt_translator_get_context, n0 = rmt_translator_get_context((const size_t *) a1, (void **) a0); NIP) \
YV(rmt, rmt_write_sample, n0 = rmt_write_sample((rmt_channel_t) n3, b2, n1, n0); NIPn(3))
#endif
#ifndef ENABLE_CAMERA_SUPPORT
# define OPTIONAL_CAMERA_SUPPORT
#else
# ifndef SIM_PRINT_ONLY
# include "esp_camera.h"
# endif
# define OPTIONAL_CAMERA_SUPPORT \
YV(camera, esp_camera_init, n0 = esp_camera_init((camera_config_t *) a0)) \
YV(camera, esp_camera_deinit, PUSH esp_camera_deinit()) \
YV(camera, esp_camera_fb_get, PUSH esp_camera_fb_get()) \
YV(camera, esp_camera_fb_return, esp_camera_fb_return((camera_fb_t *) a0); DROP) \
YV(camera, esp_camera_sensor_get, PUSH esp_camera_sensor_get())
#endif
#ifndef ENABLE_SOCKETS_SUPPORT
# define OPTIONAL_SOCKETS_SUPPORT
#else
# ifndef SIM_PRINT_ONLY
# include <errno.h>
# include <netdb.h>
# include <sys/select.h>
# include <sys/socket.h>
# include <sys/time.h>
@ -389,6 +338,13 @@ static cell_t TimerIsrRegister(cell_t group, cell_t timer, cell_t xt, cell_t arg
YV(sockets, sockaccept, n0 = accept(n2, (struct sockaddr *) a1, (socklen_t *) a0); NIPn(2)) \
YV(sockets, select, n0 = select(n4, (fd_set *) a3, (fd_set *) a2, (fd_set *) a1, (struct timeval *) a0); NIPn(4)) \
YV(sockets, poll, n0 = poll((struct pollfd *) a2, (nfds_t) n1, n0); NIPn(2)) \
YV(sockets, send, n0 = send(n3, a2, n1, n0); NIPn(3)) \
YV(sockets, sendto, n0 = sendto(n5, a4, n3, n2, (const struct sockaddr *) a1, n0); NIPn(5)) \
YV(sockets, sendmsg, n0 = sendmsg(n2, (const struct msghdr *) a1, n0); NIPn(2)) \
YV(sockets, recv, n0 = recv(n3, a2, n1, n0); NIPn(3)) \
YV(sockets, recvfrom, n0 = recvfrom(n5, a4, n3, n2, (struct sockaddr *) a1, (socklen_t *) a0); NIPn(5)) \
YV(sockets, recvmsg, n0 = recvmsg(n2, (struct msghdr *) a1, n0); NIPn(2)) \
YV(sockets, gethostbyname, n0 = (cell_t) gethostbyname(c0)) \
XV(sockets, "errno", ERRNO, PUSH errno)
#endif
@ -424,7 +380,8 @@ static cell_t TimerIsrRegister(cell_t group, cell_t timer, cell_t xt, cell_t arg
XV(SD_MMC, "SD_MMC.end", SD_MMC_END, SD_MMC.end()) \
XV(SD_MMC, "SD_MMC.cardType", SD_MMC_CARD_TYPE, PUSH SD_MMC.cardType()) \
XV(SD_MMC, "SD_MMC.totalBytes", SD_MMC_TOTAL_BYTES, PUSH SD_MMC.totalBytes()) \
XV(SD_MMC, "SD_MMC.usedBytes", SD_MMC_USED_BYTES, PUSH SD_MMC.usedBytes())
XV(SD_MMC, "SD_MMC.usedBytes", SD_MMC_USED_BYTES, PUSH SD_MMC.usedBytes()) \
XV(SD_MMC, "SD_MMC.setPins", SD_MMC_SET_PINS, n0 = SD_MMC.setPins(n5, n4, n3, n2, n1, n0); NIPn(5))
#endif
#ifndef ENABLE_I2C_SUPPORT
@ -449,37 +406,6 @@ static cell_t TimerIsrRegister(cell_t group, cell_t timer, cell_t xt, cell_t arg
XV(Wire, "Wire.flush", WIRE_FLUSH, Wire.flush())
#endif
#ifndef ENABLE_SERIAL_BLUETOOTH_SUPPORT
# define OPTIONAL_SERIAL_BLUETOOTH_SUPPORT
#else
# ifndef SIM_PRINT_ONLY
# include "esp_bt_device.h"
# include "BluetoothSerial.h"
# define bt0 ((BluetoothSerial *) a0)
# endif
# define OPTIONAL_SERIAL_BLUETOOTH_SUPPORT \
XV(bluetooth, "SerialBT.new", SERIALBT_NEW, PUSH new BluetoothSerial()) \
XV(bluetooth, "SerialBT.delete", SERIALBT_DELETE, delete bt0; DROP) \
XV(bluetooth, "SerialBT.begin", SERIALBT_BEGIN, n0 = bt0->begin(c2, n1); NIPn(2)) \
XV(bluetooth, "SerialBT.end", SERIALBT_END, bt0->end(); DROP) \
XV(bluetooth, "SerialBT.available", SERIALBT_AVAILABLE, n0 = bt0->available()) \
XV(bluetooth, "SerialBT.readBytes", SERIALBT_READ_BYTES, n0 = bt0->readBytes(b2, n1); NIPn(2)) \
XV(bluetooth, "SerialBT.write", SERIALBT_WRITE, n0 = bt0->write(b2, n1); NIPn(2)) \
XV(bluetooth, "SerialBT.flush", SERIALBT_FLUSH, bt0->flush(); DROP) \
XV(bluetooth, "SerialBT.hasClient", SERIALBT_HAS_CLIENT, n0 = bt0->hasClient()) \
XV(bluetooth, "SerialBT.enableSSP", SERIALBT_ENABLE_SSP, bt0->enableSSP(); DROP) \
XV(bluetooth, "SerialBT.setPin", SERIALBT_SET_PIN, n0 = bt0->setPin(c1); NIP) \
XV(bluetooth, "SerialBT.unpairDevice", SERIALBT_UNPAIR_DEVICE, \
n0 = bt0->unpairDevice(b1); NIP) \
XV(bluetooth, "SerialBT.connect", SERIALBT_CONNECT, n0 = bt0->connect(c1); NIP) \
XV(bluetooth, "SerialBT.connectAddr", SERIALBT_CONNECT_ADDR, n0 = bt0->connect(b1); NIP) \
XV(bluetooth, "SerialBT.disconnect", SERIALBT_DISCONNECT, n0 = bt0->disconnect()) \
XV(bluetooth, "SerialBT.connected", SERIALBT_CONNECTED, n0 = bt0->connected(n1); NIP) \
XV(bluetooth, "SerialBT.isReady", SERIALBT_IS_READY, n0 = bt0->isReady(n2, n1); NIPn(2)) \
/* Bluetooth */ \
YV(bluetooth, esp_bt_dev_get_address, PUSH esp_bt_dev_get_address())
#endif
#ifndef ENABLE_WIFI_SUPPORT
# define OPTIONAL_WIFI_SUPPORT
#else
@ -530,39 +456,9 @@ static cell_t FromIP(IPAddress ip) {
# endif
# define OPTIONAL_MDNS_SUPPORT \
/* mDNS */ \
X("MDNS.begin", MDNS_BEGIN, n0 = MDNS.begin(c0))
#endif
#ifndef ENABLE_OLED_SUPPORT
# define OPTIONAL_OLED_SUPPORT
#else
# ifndef SIM_PRINT_ONLY
# include <Adafruit_GFX.h>
# include <Adafruit_SSD1306.h>
static Adafruit_SSD1306 *oled_display = 0;
# endif
# define OPTIONAL_OLED_SUPPORT \
YV(oled, OledAddr, PUSH &oled_display) \
YV(oled, OledNew, oled_display = new Adafruit_SSD1306(n2, n1, &Wire, n0); DROPn(3)) \
YV(oled, OledDelete, delete oled_display) \
YV(oled, OledBegin, n0 = oled_display->begin(n1, n0); NIP) \
YV(oled, OledHOME, oled_display->setCursor(0,0); DROP) \
YV(oled, OledCLS, oled_display->clearDisplay()) \
YV(oled, OledTextc, oled_display->setTextColor(n0); DROP) \
YV(oled, OledPrintln, oled_display->println(c0); DROP) \
YV(oled, OledNumln, oled_display->println(n0); DROP) \
YV(oled, OledNum, oled_display->print(n0); DROP) \
YV(oled, OledDisplay, oled_display->display()) \
YV(oled, OledPrint, oled_display->write(c0); DROP) \
YV(oled, OledInvert, oled_display->invertDisplay(n0); DROP) \
YV(oled, OledTextsize, oled_display->setTextSize(n0); DROP) \
YV(oled, OledSetCursor, oled_display->setCursor(n1,n0); DROPn(2)) \
YV(oled, OledPixel, oled_display->drawPixel(n2, n1, n0); DROPn(2)) \
YV(oled, OledDrawL, oled_display->drawLine(n4, n3, n2, n1, n0); DROPn(4)) \
YV(oled, OledCirc, oled_display->drawCircle(n3,n2, n1, n0); DROPn(3)) \
YV(oled, OledCircF, oled_display->fillCircle(n3, n2, n1, n0); DROPn(3)) \
YV(oled, OledRect, oled_display->drawRect(n4, n3, n2, n1, n0); DROPn(4)) \
YV(oled, OledRectF, oled_display->fillRect(n4, n3, n2, n1, n0); DROPn(3)) \
YV(oled, OledRectR, oled_display->drawRoundRect(n5, n4, n3, n2, n1, n0); DROPn(5)) \
YV(oled, OledRectRF, oled_display->fillRoundRect(n5, n4, n3, n2, n1, n0 ); DROPn(5))
X("MDNS.begin", MDNS_BEGIN, n0 = MDNS.begin(c0) ? -1 : 0) \
X("MDNS.addService", MDNS_ADD_SERVICE, n0 = MDNS.addService(c2, c1, n0) ? -1 : 0; NIPn(2)) \
X("MDNS.setInstanceName", MDNS_SET_INSTANCE_NAME, MDNS.setInstanceName(c0); DROP) \
X("MDNS.addServiceTxt", MDNS_ADD_SERVICE_TXT, MDNS.addServiceTxt(c3, c2, c1, c0); DROPn(4))
/* alx */
#endif

View File

@ -1,59 +0,0 @@
\ Copyright 2021 Bradley D. Nelson
\
\ Licensed under the Apache License, Version 2.0 (the "License");
\ you may not use this file except in compliance with the License.
\ You may obtain a copy of the License at
\
\ http://www.apache.org/licenses/LICENSE-2.0
\
\ Unless required by applicable law or agreed to in writing, software
\ distributed under the License is distributed on an "AS IS" BASIS,
\ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
\ See the License for the specific language governing permissions and
\ limitations under the License.
internals definitions
transfer camera-builtins
forth definitions
( Lazy loaded camera handling for ESP32-CAM )
: camera r|
vocabulary camera camera definitions
also internals
transfer camera-builtins
0 constant PIXFORMAT_RGB565
1 constant PIXFORMAT_YUV422
2 constant PIXFORMAT_GRAYSCALE
3 constant PIXFORMAT_JPEG
4 constant PIXFORMAT_RGB888
5 constant PIXFORMAT_RAW
6 constant PIXFORMAT_RGB444
7 constant PIXFORMAT_RGB555
5 constant FRAMESIZE_QVGA
8 constant FRAMESIZE_VGA
( See https://github.com/espressif/esp32-camera/blob/master/driver/include/esp_camera.h )
( Settings for AI_THINKER )
create camera-config
32 , ( pin_pwdn ) -1 , ( pin_reset ) 0 , ( pin_xclk )
26 , ( pin_sscb_sda ) 27 , ( pin_sscb_scl )
35 , 34 , 39 , 36 , 21 , 19 , 18 , 5 , ( pin_d7 - pin_d0 )
25 , ( pin_vsync ) 23 , ( pin_href ) 22 , ( pin_pclk )
20000000 , ( xclk_freq_hz )
0 , ( ledc_timer ) 0 , ( ledc_channel )
here
PIXFORMAT_JPEG , ( pixel_format )
FRAMESIZE_VGA , ( frame_size ) 12 , ( jpeg_quality 0-63 low good )
here
1 , ( fb_count )
constant camera-fb-count
constant camera-format
forth definitions
camera
| evaluate ;
[THEN]

16
esp32/esp32_all_tests.fs Normal file
View File

@ -0,0 +1,16 @@
\ Copyright 2024 Bradley D. Nelson
\
\ Licensed under the Apache License, Version 2.0 (the "License");
\ you may not use this file except in compliance with the License.
\ You may obtain a copy of the License at
\
\ http://www.apache.org/licenses/LICENSE-2.0
\
\ Unless required by applicable law or agreed to in writing, software
\ distributed under the License is distributed on an "AS IS" BASIS,
\ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
\ See the License for the specific language governing permissions and
\ limitations under the License.
needs ../common/ansi.fs
needs ../common/all_tests.fs

28
esp32/esp32_boot.fs Normal file
View File

@ -0,0 +1,28 @@
\ Copyright 2023 Bradley D. Nelson
\
\ Licensed under the Apache License, Version 2.0 (the "License");
\ you may not use this file except in compliance with the License.
\ You may obtain a copy of the License at
\
\ http://www.apache.org/licenses/LICENSE-2.0
\
\ Unless required by applicable law or agreed to in writing, software
\ distributed under the License is distributed on an "AS IS" BASIS,
\ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
\ See the License for the specific language governing permissions and
\ limitations under the License.
needs ../common/phase1.fs
needs allocation.fs
needs bindings.fs
needs ../common/phase2.fs
needs ../common/phase_filetools.fs
needs platform.fs
needs ../posix/httpd.fs
needs ../posix/web_interface.fs
needs web_interface.fs
needs registers.fs
needs ../posix/telnetd.fs
needs optionals.fs
needs autoboot.fs
needs ../common/fini.fs

99
esp32/faults.h Normal file
View File

@ -0,0 +1,99 @@
// Copyright 2023 Bradley D. Nelson
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#if defined(ENABLE_ESP32_FORTH_FAULT_HANDLING)
# if defined(CONFIG_IDF_TARGET_ESP32C3)
#include <setjmp.h>
#include "riscv/csr.h"
#include "esp_heap_caps.h"
#define FORTH_VECTOR_TABLE_SIZE 32
static __thread jmp_buf g_forth_fault;
static __thread int g_forth_signal;
static void **g_forth_vector_table;
extern void *_vector_table;
#define FAULT_ENTRY \
if (setjmp(g_forth_fault)) { THROWIT(g_forth_signal); }
static void forth_faults_setup(void) {
g_forth_vector_table = (void **) malloc(sizeof(void *) * FORTH_VECTOR_TABLE_SIZE);
//g_forth_vector_table = (void **) heap_caps_malloc(sizeof(void *) * FORTH_VECTOR_TABLE_SIZE,
// MALLOC_CAP_EXEC);
void **vector_table = (void **) &_vector_table;
for (int i = 0; i < FORTH_VECTOR_TABLE_SIZE; ++i) {
g_forth_vector_table[i] = vector_table[i];
}
// TODO: Actually apply it.
/*
uint32_t mtvec_val = (uint32_t) g_forth_vector_table;
mtvec_val |= 1;
RV_WRITE_CSR(mtvec, mtvec_val);
*/
//rv_utils_set_mtvec((uint32_t) g_forth_vector_table);
}
# else
#include <setjmp.h>
#include "soc/soc.h"
#include <xtensa/xtensa_api.h>
static __thread jmp_buf g_forth_fault;
static __thread int g_forth_signal;
static __thread uint32_t g_forth_setlevel;
#define FAULT_ENTRY \
if (setjmp(g_forth_fault)) { THROWIT(g_forth_signal); }
static void IRAM_ATTR forth_exception_handler(XtExcFrame *frame) {
switch (frame->exccause) {
case EXCCAUSE_LOAD_STORE_ERROR:
case EXCCAUSE_LOAD_PROHIBITED:
case EXCCAUSE_STORE_PROHIBITED:
case EXCCAUSE_LOAD_STORE_DATA_ERROR:
case EXCCAUSE_LOAD_STORE_RING:
case EXCCAUSE_LOAD_STORE_ADDR_ERROR:
g_forth_signal = -9;
break;
case EXCCAUSE_DIVIDE_BY_ZERO: g_forth_signal = -10; break;
case EXCCAUSE_UNALIGNED: g_forth_signal = -23; break;
default: g_forth_signal = -256 - frame->exccause; break;
}
XTOS_RESTORE_INTLEVEL(g_forth_setlevel);
longjmp(g_forth_fault, 1);
}
static void forth_faults_setup(void) {
// Install exception handler for everything, as window + alloca handlers
// don't actually get dispatched.
for (int i = 0; i < 64; ++i) {
xt_set_exception_handler(i, forth_exception_handler);
}
uint32_t default_setlevel = XTOS_SET_INTLEVEL(XCHAL_EXCM_LEVEL);
XTOS_RESTORE_INTLEVEL(default_setlevel);
g_forth_setlevel = default_setlevel;
}
# endif
#else
#define forth_faults_setup()
#define FAULT_ENTRY
#endif

View File

@ -0,0 +1,27 @@
+----------------------------------+
| ESP32forth - Optional Packages |
+----------------------------------+
ESPforth supports a number of optional packages, included in this directory.
By default ESPforth will only include core functionality.
To include one or more of these modules, move them from this directory
into the parent directory, next to the ESPforth.ino file.
These are the current optional modules:
* assemblers.h - Assemblers for ESP32 Xtensa and ESP32 RISC-V
* camera.h - Support for the ESP32-CAM camera
* oled.h - Support for the SSD1306 Oled
* rmt.h - Support for RMT (Remote Control)
* serial-bluetooth.h - Support for Bluetooth serial and
bterm a Bluetooth serial redirector for the terminal
* spi-flash.h - Support for low level SPI Flash partition access
* http-client.h - Support for HTTP/HTTPS
Initially ESP32forth focused on a minimal C kernel, with most functionality
built in Forth code loaded at boot. Eventually, as support for more capabilities
were added to ESPforth, this became unsustainable.
Optional modules demonstrate good patterns for use in your own extensions
to ESP32forth. You can add you own modules by #including them from
an optional userwords.h file placed next to ESPforth.ino

View File

@ -0,0 +1,45 @@
/*
* Copyright 2023 Bradley D. Nelson
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
* ESP32forth Assemblers v{{VERSION}}
* Revision: {{REVISION}}
*/
#define OPTIONAL_ASSEMBLERS_SUPPORT \
XV(internals, "assembler-source", ASSEMBLER_SOURCE, \
PUSH assembler_source; PUSH sizeof(assembler_source) - 1) \
PLATFORM_ASSEMBLER_SUPPORT
#include "gen/esp32_assembler.h"
#if defined(__riscv)
# define PLATFORM_ASSEMBLER_SUPPORT \
XV(internals, "riscv-assembler-source", RISCV_ASSEMBLER_SOURCE, \
PUSH riscv_assembler_source; PUSH sizeof(riscv_assembler_source) - 1)
#include "gen/esp32_riscv-assembler.h"
#else
# define PLATFORM_ASSEMBLER_SUPPORT \
XV(internals, "xtensa-assembler-source", XTENSA_ASSEMBLER_SOURCE, \
PUSH xtensa_assembler_source; PUSH sizeof(xtensa_assembler_source) - 1)
#include "gen/esp32_xtensa-assembler.h"
#endif

View File

@ -0,0 +1,154 @@
\ Copyright 2022 Bradley D. Nelson
\
\ Licensed under the Apache License, Version 2.0 (the "License");
\ you may not use this file except in compliance with the License.
\ You may obtain a copy of the License at
\
\ http://www.apache.org/licenses/LICENSE-2.0
\
\ Unless required by applicable law or agreed to in writing, software
\ distributed under the License is distributed on an "AS IS" BASIS,
\ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
\ See the License for the specific language governing permissions and
\ limitations under the License.
RISC-V? [IF]
( Lazy loaded RISC-V assembler )
: riscv-assembler r|
current @
also assembler definitions
vocabulary riscv riscv definitions
32 names zero x1 x2 x3 x4 x5 x6 x7 x8 x9 x10 x11 x12 x13 x14 x15 x16 x17 x18 x19 x20 x21 x22 x23 x24 x25 x26 x27 x28 x29 x30 x31
: nop ;
: reg. ( n -- ) dup if base @ >r decimal ." x" . r> base ! else drop ." zero " then ;
: register ( -- in print ) ['] nop ['] reg. ;
: reg>reg' ( n -- n ) 8 - 7 and ;
: reg'. ( n -- ) 8 + reg. ;
: register' ( -- in print ) ['] reg>reg' ['] reg'. ;
: numeric ( -- in print ) ['] nop ['] . ;
numeric operand i : iiii i i i i ;
( Offsets for JAL )
: >ofs ( n -- n ) chere - dup 20 rshift 1 and 31 12 - lshift
over 1 rshift $3ff and 21 12 - lshift or
over 11 rshift 1 and 20 12 - lshift or
swap 12 rshift $ff and or ;
: ofs. ( n -- ) dup 31 12 - rshift 1 and 20 lshift
over 21 12 - rshift $3ff and 1 lshift or
over 20 12 - rshift 1 and 11 lshift or
swap $ff and 12 lshift or 21 sextend address @ + . ;
' >ofs ' ofs. operand ofs
: offset 20 for aft ofs then next ;
register operand rd# : rd rd# rd# rd# rd# rd# ;
register' operand rd#' : rd' rd#' rd#' rd#' ;
register operand rs1# : rs1 rs1# rs1# rs1# rs1# rs1# ;
register' operand rs1#' : rs1' rs1#' rs1#' rs1#' ;
register operand rs2# : rs2 rs2# rs2# rs2# rs2# rs2# ;
register' operand rs2#' : rs2' rs2#' rs2#' rs2#' ;
: R-TYPE { fn7 fn3 opc }
fn7 7 bits rs2 rs1 fn3 3 bits rd opc 7 bits OP ;
: I-TYPE { fn3 opc }
iiii iiii iiii rs1 fn3 3 bits rd opc 7 bits OP ;
: S-TYPE { fn3 opc }
iiii i i i rs2 rs1 fn3 3 bits i iiii opc 7 bits OP ;
: B-TYPE { fn3 opc }
iiii i i i rs2 rs1 fn3 3 bits i iiii opc 7 bits OP ;
: U-TYPE { opc }
iiii iiii iiii iiii iiii rd opc 7 bits OP ;
: J-TYPE { opc }
offset rd opc 7 bits OP ;
$37 U-TYPE LUI,
$17 U-TYPE AUIPC,
$6F J-TYPE JAL,
$0 $67 I-TYPE JALR,
$0 $63 B-TYPE BEQ, $1 $63 B-TYPE BNE,
$4 $63 B-TYPE BLT, $5 $63 B-TYPE BGE,
$6 $63 B-TYPE BLTU, $7 $63 B-TYPE BGEU,
$0 $03 I-TYPE LB, $1 $03 I-TYPE LH, $2 $03 I-TYPE LW,
$4 $03 I-TYPE LBU, $5 $03 I-TYPE LHU,
$0 $23 S-TYPE SB, $1 $23 S-TYPE SH, $2 $23 S-TYPE SW,
$0 $13 I-TYPE ADDI, $2 $13 I-TYPE SLTI, $3 $13 I-TYPE SLTIU,
$4 $13 I-TYPE XORI, $6 $13 I-TYPE ORI, $7 $13 I-TYPE ANDI,
$00 $1 $13 R-TYPE SLLI,
$00 $5 $13 R-TYPE SRLI, $20 $5 $13 R-TYPE SRAI,
$00 $0 $33 R-TYPE ADD, $20 $0 $33 R-TYPE SUB,
$00 $1 $33 R-TYPE SLL, $00 $2 $33 R-TYPE SLT,
$00 $3 $33 R-TYPE SLTU, $00 $4 $33 R-TYPE XOR,
$00 $5 $33 R-TYPE SRL, $20 $5 $33 R-TYPE SRA,
$00 $6 $33 R-TYPE OR, $20 $7 $33 R-TYPE AND,
( TODO FENCE, FENCE.I )
o o o o o o o o o o o o o o o o o o o o o o o o o o o o l l l l OP ECALL,
o o o o o o o o o o o l o o o o o o o o o o o o o o o o l l l l OP EBREAK,
( TODO CSR* )
o o o o o o o o o o o o o o o o OP C.ILL,
o o o i i i i i i i i rd' o o OP C.ADDI4SP,
o o l i i i rs1' i i rd' o o OP C.FLD,
o l o i i i rs1' i i rd' o o OP C.LW,
o l l i i i rs1' i i rd' o o OP C.FLW,
( 4 reserved )
l o l i i i rs1' i i rd' o o OP C.FSD,
l l o i i i rs1' i i rd' o o OP C.SW,
l l l i i i rs1' i i rd' o o OP C.FSW,
o o o o o o o o o o o o o o o l OP C.NOP,
o o o i rs1 i i i i i o l OP C.ADDI,
o o l i i i i i i i i i i i o l OP C.JAL,
o l o i rd i i i i i o l OP C.LI,
o l l i rd i i i i i o l OP C.LUI,
l o o i o o rs1' i i i i i o l OP C.SRLI,
l o o i o l rs1' i i i i i o l OP C.SRAI,
l o o i l o rs1' i i i i i o l OP C.ANDI,
l o o o l l rs1' o o rs2' o l OP C.SUB,
l o o o l l rs1' o l rs2' o l OP C.XOR,
l o o o l l rs1' l o rs2' o l OP C.OR,
l o o o l l rs1' l l rs2' o l OP C.AND,
l o o l l l rs1' o o rs2' o l OP C.SUBW,
l o o l l l rs1' o l rs2' o l OP C.ADDW,
l o l i i i i i i i i i i i o l OP C.J,
l l o i i i rs1' i i i i i o l OP BEQZ,
l l l i i i rs1' i i i i i o l OP BNEZ,
o o o i rs1 i i i i i l o OP C.SLLI,
o o l i rd i i i i i l o OP C.FLDSP,
o l o i rd i i i i i l o OP C.LWSP,
o l l i rd i i i i i l o OP C.FLWSP,
l o o o rs1 o o o o o l o OP C.JR,
l o o o rd rs2 l o OP C.MV,
l o o l o o o o o o o o o o l o OP C.EBREAK,
l o o l rs1 o o o o o l o OP C.JALR,
l o o l rd rs2 l o OP C.ADD,
l o l i i i i i i rs2 l o OP C.FSDSP,
l l o i i i i i i rs2 l o OP C.SWSP,
l l l i i i i i i rs2 l o OP C.FSWSP,
also forth definitions
: riscv-assembler riscv ;
previous previous
riscv-assembler
current !
| evaluate ;
[THEN]

View File

@ -0,0 +1,311 @@
\ Copyright 2022 Bradley D. Nelson
\
\ Licensed under the Apache License, Version 2.0 (the "License");
\ you may not use this file except in compliance with the License.
\ You may obtain a copy of the License at
\
\ http://www.apache.org/licenses/LICENSE-2.0
\
\ Unless required by applicable law or agreed to in writing, software
\ distributed under the License is distributed on an "AS IS" BASIS,
\ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
\ See the License for the specific language governing permissions and
\ limitations under the License.
Xtensa? [IF]
( Lazy loaded xtensa assembler )
: xtensa-assembler r|
current @
also assembler definitions
vocabulary xtensa xtensa definitions
16 names a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 a15
: nop ;
: reg. ( n -- ) base @ >r decimal ." a" . r> base ! ;
: register ( -- in print ) ['] nop ['] reg. ;
: numeric ( -- in print ) ['] nop ['] . ;
numeric operand im
: imm4 im im im im ;
: imm8 imm4 imm4 ;
: imm16 imm8 imm8 ;
: sr imm8 ;
( Offsets for J and branches )
: >ofs ( n -- n ) chere - 4 - ;
: ofs8. ( n -- ) 8 sextend address @ + 4 + . ;
: ofs12. ( n -- ) 12 sextend address @ + 4 + . ;
: ofs18. ( n -- ) 18 sextend address @ + 4 + . ;
' >ofs ' ofs8. operand ofs8
' >ofs ' ofs12. operand ofs12
' >ofs ' ofs18. operand ofs18
: offset8 8 for aft ofs8 then next ;
: offset12 12 for aft ofs12 then next ;
: offset18 18 for aft ofs18 then next ;
( Offsets for CALL* )
: >cofs ( n -- n ) chere - 2 rshift 1- ;
: cofs. ( n -- ) 18 sextend 1+ 2 lshift address @ 3 invert and + . ;
' >cofs ' cofs. operand cofs
: coffset18 18 for aft cofs then next ;
( Frame size of ENTRY )
: >entry12 ( n -- n ) 3 rshift ;
: entry12. ( n -- ) 3 lshift . ;
' >entry12 ' entry12. operand entry12'
: entry12 12 for aft entry12' then next ;
: >sa ( n -- n ) 32 swap - ;
: sa. ( n -- ) 32 swap - . ;
' >sa ' sa. operand sa
numeric operand x : xxxx x x x x ;
numeric operand i : iiii i i i i ;
numeric operand w
numeric operand y
numeric operand b : bbbb b b b b ;
register operand r : rrrr r r r r ;
register operand s : ssss s s s s ;
register operand t : tttt t t t t ;
imm4 ssss tttt l o o o OP L32I.N,
imm4 ssss tttt l o o l OP S32I.N,
rrrr ssss tttt l o l o OP ADD.N,
rrrr ssss imm4 l o l l OP ADDI.N,
iiii ssss l o i i l l o o OP BEQZ.N,
iiii ssss l l i i l l o o OP BNEZ.N,
iiii ssss o i i i l l o o OP MOVI.N,
o o o o ssss tttt l l o l OP MOV.N,
l l l l ssss o o l o l l o l OP BREAK.N,
l l l l o o o o o o o o l l o l OP RET.N,
l l l l o o o o o o o l l l o l OP RETW.N,
l l l l o o o o o o l l l l o l OP NOP.N,
l l l l o o o o o l l o l l o l OP ILL.N,
o o o o o o o o o o o o o o o o o o o o o o o o OP ILL,
o o o o o o o o o o o o o o o o l o o o o o o o OP RET,
o o o o o o o o o o o o o o o o l o o l o o o o OP RETW,
o o o o o o o o o o l o o o o o o o o o o o o o OP ISYNC,
o o o o o o o o o o l o o o o o o o o l o o o o OP RSYNC,
o o o o o o o o o o l o o o o o o o l o o o o o OP ESYNC,
o o o o o o o o o o l o o o o o o o l l o o o o OP DSYNC,
o o o o o o o o o o l o o o o o l o o o o o o o OP EXCW,
o o o o o o o o o o l o o o o o l l o o o o o o OP MEMW,
o o o o o o o o o o l o o o o o l l o l o o o o OP EXTW,
o o o o o o o o o o l o o o o o l l l l o o o o OP NOP,
o o o o o o o o o o l l o o o o o o o o o o o o OP RFE,
o o o o o o o o o o l l o o o o o o l o o o o o OP RFME,
o o o o o o o o o o l l o o o l o o o o o o o o OP RFUE,
o o o o o o o o o o l l o o l o o o o o o o o o OP RFDE,
o o o o o o o o o o l l o l o o o o o o o o o o OP RFWO,
o o o o o o o o o o l l o l o l o o o o o o o o OP RFWU,
o o o o o o o o o l o l o o o o o o o o o o o o OP SYSCALL,
o o o o o o o o o l o l o o o l o o o o o o o o OP SIMCALL,
l l l l o o o l l l l o o o o s o o o l o o o o OP RFDD,
l l l l o o o l l l l o o o o o o o o o o o o o OP RFDO,
o l l o o o o o rrrr o o o o tttt o o o o OP NEG,
o l l o o o o o rrrr o o o l tttt o o o o OP ABS,
o l l o o o o l sr tttt o o o o OP XSR,
: ALU 4 bits o o o o rrrr ssss tttt o o o o OP ;
$1 ALU AND, $2 ALU OR, $3 ALU XOR,
( $6 ABS/NEG )
$8 ALU ADD, $9 ALU ADDX2, $a ALU ADDX4, $b ALU ADDX8,
$c ALU SUB, $d ALU SUBX2, $e ALU SUBX4, $f ALU SUBX8,
: ANYALL o o o o o o o o l o 2 bits ssss tttt o o o o OP ;
$0 ANYALL ANY4, $1 ANYALL ALL4, $2 ANYALL ANY8, $3 ANYALL ALL8,
: ALU2 4 bits o o l o rrrr ssss tttt o o o o OP ;
$0 ALU2 ANDB, $1 ALU2 ANDBC, $2 ALU2 ORB, $3 ALU2 ORBC,
$4 ALU2 XORB,
$8 ALU2 MULL, $a ALU2 MULUH, $b ALU2 MULSH,
$c ALU2 QUOU, $d ALU2 QUOS, $e ALU2 REMU, $f ALU2 REMS,
: BRANCH1 offset8 4 bits ssss tttt o l l l OP ;
$0 BRANCH1 BNONE, $1 BRANCH1 BEQ, $2 BRANCH1 BLT, $3 BRANCH1 BLTU,
$4 BRANCH1 BALL, $5 BRANCH1 BBC,
offset8 o l l b ssss bbbb o l l l OP BBCI,
$8 BRANCH1 BANY, $9 BRANCH1 BNE, $a BRANCH1 BGE, $b BRANCH1 BGEU,
$c BRANCH1 BNALL, $d BRANCH1 BBS,
offset8 l l l b ssss bbbb o l l l OP BBSI,
: BRANCH2 offset12 ssss 4 bits o l l o OP ;
: BRANCH2a offset8 rrrr ssss 4 bits o l l o OP ;
: BRANCH2e entry12 ssss 4 bits o l l o OP ;
( $0 J, ) $1 BRANCH2 BEQZ, $2 BRANCH2a BEQI, $3 BRANCH2e ENTRY,
( $4 J, ) $5 BRANCH2 BNEZ, $6 BRANCH2a BNEI, ( BRANCH2b's )
( $8 J, ) $9 BRANCH2 BLTZ, $a BRANCH2a BLTI, $b BRANCH2a BLTUI,
( $c J, ) $d BRANCH2 BGEZ, $e BRANCH2a BGEI, $f BRANCH2a BGEUI,
offset18 o o o l l o OP J,
: BRANCH2b offset8 4 bits ssss o l l l o l l o OP ;
$0 BRANCH2b BF, $1 BRANCH2b BT,
$8 BRANCH2b LOOP, $9 BRANCH2b LOOPNEZ, $a BRANCH2b LOOPGTZ,
: CALLOP coffset18 2 bits o l o l OP ;
0 CALLOP CALL0, 1 CALLOP CALL4, 2 CALLOP CALL8, 3 CALLOP CALL12,
: CALLXOP o o o o o o o o o o o o ssss l l 2 bits o o o o OP ;
0 CALLXOP CALLX0, 1 CALLXOP CALLX4, 2 CALLXOP CALLX8, 3 CALLXOP CALLX12,
o o o o o o o o o l o o ssss tttt o o o o OP BREAK,
o o l l o o l l rrrr ssss tttt o o o o OP CLAMPS,
: CACHING1 imm8 o l l l ssss 4 bits o o l o OP ;
$0 CACHING1 DPFR, $1 CACHING1 DPFW, $2 CACHING1 DPFRO, $3 CACHING1 DPFWO,
$4 CACHING1 DHWB, $5 CACHING1 DHWBI, $6 CACHING1 DHI, $7 CACHING1 DII,
( $8 CACHING2 ) ( ?? ) ( ?? ) ( ?? )
$c CACHING1 IPF, ( $d CACHING2 ) $e CACHING1 IHI, $f CACHING1 III,
: CACHING2 imm4 4 bits o l l l ssss 4 bits o o l o OP ;
$0 $8 CACHING2 DPFL, $2 $8 CACHING2 DHU, $3 $8 CACHING2 DIU,
$4 $8 CACHING2 DIWB, $5 $8 CACHING2 DIWBI,
$0 $d CACHING2 IPFL, $2 $d CACHING2 IHU, $3 $d CACHING2 IIU,
iiii iiii l o l o iiii tttt o o l o OP MOVI,
: LDSTORE imm8 4 bits ssss tttt o o l o OP ;
$0 LDSTORE L8UI, $1 LDSTORE L16UI, $2 LDSTORE L32I, ( $3 CACHING )
$4 LDSTORE S8I, $5 LDSTORE S16I, $6 LDSTORE S32I,
$9 LDSTORE L16SI, ( $a MOVI ) $b LDSTORE L32AI,
$c LDSTORE ADDI, $d LDSTORE ADDMI, $e LDSTORE S32C1I, $f LDSTORE S32RI,
o l o o l o o l rrrr ssss tttt o o o o OP S32E,
x x x x o l o sa rrrr sa sa sa sa tttt o o o o OP EXTUI,
imm16 tttt o o o l OP L32R,
l o o l o o o o o o w w ssss o o o o o l o o OP LDDEC,
l o o o o o o o o o w w ssss o o o o o l o o OP LDINC,
imm8 o o o o ssss tttt o o l l OP LSI,
imm8 l o o o ssss tttt o o l l OP LSIU,
o l o l o o o o l l o o ssss o o o o o o o o OP IDTLB,
o l o l o o o o o l o o ssss o o o o o o o o OP IITLB,
o o o o o o o o o o o o ssss l o l o o o o o OP JX,
l l l l o o o l l o o o ssss tttt o o o o OP LDCT,
l l l l o o o l o o o o ssss tttt o o o o OP LICT,
l l l l o o o l o o l o ssss tttt o o o o OP LICW,
o o o o l o o l rrrr ssss tttt o o o o OP L32E,
o o o o l o o o rrrr ssss tttt o o o o OP LSX,
o o o l l o o o rrrr ssss tttt o o o o OP LSXU,
o o l o o o o o rrrr ssss tttt o o o o OP MOV,
: CONDOP 4 bits o o l l rrrr ssss tttt o o o o OP ;
$4 CONDOP MIN, $5 CONDOP MAX, $6 CONDOP MINU, $7 CONDOP MAXU,
$8 CONDOP MOVEQZ, $9 CONDOP MOVNEZ, $a CONDOP MOVLTZ, $b CONDOP MOVGEZ,
$c CONDOP MOVF,
: ALU.S 4 bits l o l o rrrr ssss tttt o o o o OP ;
$0 ALU.S ADD.S, $1 ALU.S SUB.S, $2 ALU.S MUL.S,
$4 ALU.S MADD.S, $5 ALU.S MSUB.S,
$8 ALU.S ROUND.S, $9 ALU.S TRUNC.S, $a ALU.S FLOOR.S, $b ALU.S CEIL.S,
$c ALU.S FLOAT.S, $d ALU.S UFLOAT.S, $e ALU.S UTRUNC.S,
: ALU2.S l l l l l o l o rrrr ssss 4 bits o o o o OP ;
$0 ALU2.S MOV.S, $1 ALU2.S ABS.S,
$4 ALU2.S RFR, $5 ALU2.S WFR, $6 ALU2.S NEG.S,
: CMPSOP 4 bits l o l l rrrr ssss tttt o o o o OP ;
$1 CMPSOP UN.S, $2 CMPSOP OEQ.S, $3 CMPSOP UEQ.S,
$4 CMPSOP OLT.S, $5 CMPSOP ULT.S, $6 CMPSOP OLE.S, $7 CMPSOP ULE.S,
$8 CMPSOP MOVEQZ.S, $9 CMPSOP MOVNEZ.S, $a CMPSOP MOVLTZ.S, $b CMPSOP MOVGEZ.S,
$c CMPSOP MOVF.S, $d CMPSOP MOVT.S,
o o o o o o o o o o o l ssss tttt o o o o OP MOVSP,
l l o l o o l l rrrr ssss tttt o o o o OP MOVT,
: MUL.AA o l l l o l 2 bits o o o o ssss tttt o l o o OP ;
0 MUL.AA MUL.AA.LL, 1 MUL.AA MUL.AA.HL, 2 MUL.AA MUL.AA.LH, 3 MUL.AA MUL.AA.HH,
: MUL.AD o l l l o l 2 bits o o o o ssss o y o o o l o o OP ;
0 MUL.AD MUL.AD.LL, 1 MUL.AD MUL.AD.HL, 2 MUL.AD MUL.AD.LH, 3 MUL.AD MUL.AD.HH,
: MUL.DA o l l o o l 2 bits o x o o o o o o tttt o l o o OP ;
0 MUL.DA MUL.DA.LL, 1 MUL.DA MUL.DA.HL, 2 MUL.DA MUL.DA.LH, 3 MUL.DA MUL.DA.HH,
: MUL.DD o o l o o l 2 bits o x o o o o o o o y o o o l o o OP ;
0 MUL.DD MUL.DD.LL, 1 MUL.DD MUL.DD.HL, 2 MUL.DD MUL.DD.LH, 3 MUL.DD MUL.DD.HH,
l l o l o o o l rrrr ssss tttt o o o o OP MUL16S,
l l o o o o o l rrrr ssss tttt o o o o OP MUL16U,
: MULA.AA o l l l l o 2 bits ssss tttt o l o o OP ;
0 MULA.AA MULA.AA.LL, 1 MULA.AA MULA.AA.HL, 2 MULA.AA MULA.AA.LH, 3 MULA.AA MULA.AA.HH,
: MULA.AD o o l l l o 2 bits ssss tttt o l o o OP ;
0 MULA.AD MULA.AD.LL, 1 MULA.AD MULA.AD.HL, 2 MULA.AD MULA.AD.LH, 3 MULA.AD MULA.AD.HH,
: MULA.DA o l l o l o 2 bits o x o o o o o o tttt o l o o OP ;
0 MULA.DA MULA.DA.LL, 1 MULA.DA MULA.DA.HL, 2 MULA.DA MULA.DA.LH, 3 MULA.DA MULA.DA.HH,
: MULA.DA.LDDEC o l o l l o 2 bits o x o o o o o o tttt o l o o OP ;
0 MULA.DA.LDDEC MULA.DA.LL.LDDEC, 1 MULA.DA.LDDEC MULA.DA.HL.LDDEC,
2 MULA.DA.LDDEC MULA.DA.LH.LDDEC, 3 MULA.DA.LDDEC MULA.DA.HH.LDDEC,
: MULA.DA.LDINC o l o o l o 2 bits o x w o o o o o tttt o l o o OP ;
0 MULA.DA.LDINC MULA.DA.LL.LDINC, 1 MULA.DA.LDINC MULA.DA.HL.LDINC,
2 MULA.DA.LDINC MULA.DA.LH.LDINC, 3 MULA.DA.LDINC MULA.DA.HH.LDINC,
: MULA.DD o o l o l o 2 bits o x o o o o o o o y o o o l o o OP ;
0 MULA.DD MULA.DD.LL, 1 MULA.DD MULA.DD.HL, 2 MULA.DD MULA.DD.LH, 3 MULA.DD MULA.DD.HH,
: MULA.DD.LDDEC o o o l l o 2 bits o x w w o o o o tttt o l o o OP ;
0 MULA.DD.LDDEC MULA.DD.LL.LDDEC, 1 MULA.DD.LDDEC MULA.DD.HL.LDDEC,
2 MULA.DD.LDDEC MULA.DD.LH.LDDEC, 3 MULA.DD.LDDEC MULA.DD.HH.LDDEC,
: MULA.DD.LDINC o o o o l o 2 bits o x w w o o o o tttt o l o o OP ;
0 MULA.DD.LDINC MULA.DD.LL.LDINC, 1 MULA.DD.LDINC MULA.DD.HL.LDINC,
2 MULA.DD.LDINC MULA.DD.LH.LDINC, 3 MULA.DD.LDINC MULA.DD.HH.LDINC,
: MULS.AA o l l l l o 2 bits o o o o ssss tttt o l o o OP ;
0 MULS.AA MULA.AA.LL, 1 MULS.AA MULA.AA.HL, 2 MULS.AA MULA.AA.LH, 3 MULS.AA MULA.AA.HH,
: MULS.AD o o l l l o 2 bits o o o o ssss o y o o o l o o OP ;
0 MULS.AD MULA.AD.LL, 1 MULS.AD MULA.AD.HL, 2 MULS.AD MULA.AD.LH, 3 MULS.AD MULA.AD.HH,
: MULS.DA o l l o l o 2 bits o x o o o o o o tttt o l o o OP ;
0 MULS.DA MULA.DA.LL, 1 MULS.DA MULA.DA.HL, 2 MULS.DA MULA.DA.LH, 3 MULS.DA MULA.DA.HH,
: MULS.DD o o l o l o 2 bits o x o o o o o o o y o o o l o o OP ;
0 MULS.DD MULA.DD.LL, 1 MULS.DD MULA.DD.HL, 2 MULS.DD MULA.DD.LH, 3 MULS.DD MULA.DD.HH,
o l o o o o o o l l l o ssss tttt o o o o OP NSA,
o l o o o o o o l l l l ssss tttt o o o o OP NSAU,
o l o l o o o o l l o l ssss tttt o o o o OP PDTLB,
o l o l o o o o o l o l ssss tttt o o o o OP PITLB,
o l o l o o o o l o l l ssss tttt o o o o OP RDTLB0,
o l o l o o o o l l l l ssss tttt o o o o OP RDTLB1,
o l o o o o o o o l l o ssss tttt o o o o OP RER,
o l o l o o o o o o l l ssss tttt o o o o OP RITLB0,
o l o l o o o o o l l l ssss tttt o o o o OP RITLB1,
o l o o o o o o l o o o o o o o imm4 o o o o OP ROTW,
o o o o o o o o o o l l imm4 o o o l o o o o OP RFI,
o o o o o o o o o l l o imm4 tttt o o o o OP RSIL,
o o o o o o l l sr tttt o o o o OP RSR,
l l l o o o l l rrrr ssss tttt o o o o OP RUR,
l l l l o o o l l o o l ssss tttt o o o o OP SDCT,
o o l o o o l l rrrr ssss tttt o o o o OP SEXT,
l l l l o o o l o o o l ssss tttt o o o o OP SICT,
l l l l o o o l o o l l ssss tttt o o o o OP SICW,
l o l o o o o l rrrr ssss o o o o o o o o OP SLL,
o o o sa o o o l rrrr ssss sa sa sa sa o o o o OP SLLI,
l o l l o o o l rrrr o o o o tttt o o o o OP SRA,
o o l x o o o l rrrr xxxx tttt o o o o OP SRAI,
l o o o o o o l rrrr ssss tttt o o o o OP SRC,
l o o l o o o l rrrr o o o o tttt o o o o OP SRL,
o l o o o o o l rrrr xxxx tttt o o o o OP SRLI,
o l o o o o o o o o l l ssss o o o o o o o o OP SSA8B,
o l o o o o o o o o l o ssss o o o o o o o o OP SSA8L,
o l o o o o o o o l o o xxxx o o o x o o o o OP SSAI,
imm8 o l o o ssss tttt o o l l OP SSI,
imm8 l l o o ssss tttt o o l l OP SSIU,
o l o o o o o o o o o l ssss o o o o o o o o OP SSL,
o l o o o o o o o o o o ssss o o o o o o o o OP SSR,
o l o o l o o o rrrr ssss tttt o o o o OP SSX,
o l o l l o o o rrrr ssss tttt o o o o OP SSXU,
( TODO: UMUL.AA.* )
o o o o o o o o o l l l imm4 o o o o o o o o OP WAITI,
o l o l o o o o l l l o ssss tttt o o o o OP WDTLB,
o l o o o o o o o l l l ssss tttt o o o o OP WER,
o l o l o o o o o l l o ssss tttt o o o o OP WITLB,
o o o l o o l l sr tttt o o o o OP WSR,
l l l l o o l l sr tttt o o o o OP WUR,
also forth definitions
: xtensa-assembler xtensa ;
previous previous
xtensa-assembler
current !
| evaluate ;
[THEN]

View File

@ -0,0 +1,130 @@
\ Copyright 2021 Bradley D. Nelson
\
\ Licensed under the Apache License, Version 2.0 (the "License");
\ you may not use this file except in compliance with the License.
\ You may obtain a copy of the License at
\
\ http://www.apache.org/licenses/LICENSE-2.0
\
\ Unless required by applicable law or agreed to in writing, software
\ distributed under the License is distributed on an "AS IS" BASIS,
\ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
\ See the License for the specific language governing permissions and
\ limitations under the License.
internals definitions
transfer camera-builtins
DEFINED? esp_camera_init [IF]
forth definitions
( Lazy loaded camera handling for ESP32-CAM )
: camera r|
vocabulary camera camera definitions
also internals
transfer camera-builtins
0 constant PIXFORMAT_RGB565
1 constant PIXFORMAT_YUV422
2 constant PIXFORMAT_GRAYSCALE
3 constant PIXFORMAT_JPEG
4 constant PIXFORMAT_RGB888
5 constant PIXFORMAT_RAW
6 constant PIXFORMAT_RGB444
7 constant PIXFORMAT_RGB555
0 constant FRAMESIZE_96x96 ( 96x96)
1 constant FRAMESIZE_QQVGA ( 160x120 )
2 constant FRAMESIZE_QCIF ( 176x144 )
3 constant FRAMESIZE_HQVGA ( 240x176 )
4 constant FRAMESIZE_240x240 ( 176x144 )
5 constant FRAMESIZE_QVGA ( 320x240 )
6 constant FRAMESIZE_CIF ( 400x296 )
7 constant FRAMESIZE_HVGA ( 480x320 )
8 constant FRAMESIZE_VGA ( 640x480 )
9 constant FRAMESIZE_SVGA ( 800x600 )
10 constant FRAMESIZE_XGA ( 1024x768 )
11 constant FRAMESIZE_HD ( 1280x720 )
12 constant FRAMESIZE_SXGA ( 1280x1024 )
13 constant FRAMESIZE_UXGA ( 1600x1200 )
( See https://github.com/espressif/esp32-camera/blob/master/driver/include/esp_camera.h )
( Settings for AI_THINKER )
create camera-config
32 , ( pin_pwdn ) -1 , ( pin_reset ) 0 , ( pin_xclk )
26 , ( pin_sscb_sda ) 27 , ( pin_sscb_scl )
35 , 34 , 39 , 36 , 21 , 19 , 18 , 5 , ( pin_d7 - pin_d0 )
25 , ( pin_vsync ) 23 , ( pin_href ) 22 , ( pin_pclk )
20000000 , ( xclk_freq_hz )
0 , ( ledc_timer ) 0 , ( ledc_channel )
here
PIXFORMAT_JPEG , ( pixel_format )
here
FRAMESIZE_VGA , ( frame_size )
here
12 , ( jpeg_quality 0-63 low good )
here
1 , ( fb_count )
constant camera-fb-count
constant camera-jpeg-quality
constant camera-frame-size
constant camera-format
: field@ ( n -- n ) dup create , cell+ does> @ + @ ;
0
field@ fb->buf
field@ fb->len
field@ fb->width
field@ fb->height
field@ fb->format
field@ fb->sec
field@ fb->usec
drop
5 cells
field@ s->xclk_freq_hz ( a )
field@ s->init_status ( s )
field@ s->reset ( s )
field@ s->set_pixformat ( s pixformat )
field@ s->set_framesize ( s framesize )
field@ s->set_contrast ( s level )
field@ s->set_brightness ( s level )
field@ s->set_saturation ( s level )
field@ s->set_sharpness ( s level )
field@ s->set_denoise ( s level )
field@ s->set_gainceiling ( s gainceil )
field@ s->set_quality ( s quality )
field@ s->set_colorbar ( s enable )
field@ s->set_whitebal ( s enable )
field@ s->set_gain_ctrl ( s enable )
field@ s->set_exposure_ctrl ( s enable )
field@ s->set_hmirror ( s enable )
field@ s->set_vflip ( s enable )
field@ s->set_aec2 ( s enable )
field@ s->set_awb_gain ( s enable )
field@ s->set_agc_gain ( s gain )
field@ s->set_aec_value ( s gain )
field@ s->set_special_effect ( s effect )
field@ s->set_wb_mode ( s mode )
field@ s->set_ae_level ( s level )
field@ s->set_raw_gma ( s enable )
field@ s->set_lenc ( s enable )
field@ s->get_reg ( s reg mask )
field@ s->set_reg ( s reg mask value )
field@ s->set_res_raw ( s startX startY endX endY offsetX offsetY totalX totalY outputX outputY scale binning )
field@ s->set_pll ( s bypass mul sys root pre seld5 pclken pclk )
field@ s->set_xclk ( s time xclk )
drop
forth definitions
camera
| evaluate ;
[ELSE]
forth definitions
[THEN]

View File

@ -0,0 +1,34 @@
// Copyright 2023 Bradley D. Nelson
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/*
* ESP32forth ESP32-CAM Camera v{{VERSION}}
* Revision: {{REVISION}}
*/
#include "esp_camera.h"
#define OPTIONAL_CAMERA_VOCABULARY V(camera)
#define OPTIONAL_CAMERA_SUPPORT \
XV(internals, "camera-source", CAMERA_SOURCE, \
PUSH camera_source; PUSH sizeof(camera_source) - 1) \
YV(camera, esp_camera_init, n0 = esp_camera_init((camera_config_t *) a0)) \
YV(camera, esp_camera_deinit, PUSH esp_camera_deinit()) \
YV(camera, esp_camera_fb_get, PUSH esp_camera_fb_get()) \
YV(camera, esp_camera_fb_return, esp_camera_fb_return((camera_fb_t *) a0); DROP) \
YV(camera, esp_camera_sensor_get, PUSH esp_camera_sensor_get()) \
YV(camera, esp_camera_save_to_nvs, n0 = esp_camera_save_to_nvs(c0)) \
YV(camera, esp_camera_load_from_nvs, n0 = esp_camera_load_from_nvs(c0))
#include "gen/esp32_camera.h"

View File

@ -12,6 +12,8 @@
\ See the License for the specific language governing permissions and
\ limitations under the License.
needs camera.fs
( Lazy loaded Camera Server )
: camera-server r~

View File

@ -0,0 +1,52 @@
// Copyright 2024 Bradley D. Nelson
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/*
* ESP32forth RMT v{{VERSION}}
* Revision: {{REVISION}}
*/
#include "HTTPClient.h"
#define OPTIONAL_HTTP_CLIENT_VOCABULARY V(HTTPClient)
#define OPTIONAL_HTTP_CLIENT_SUPPORT \
XV(HTTPClient, "NetworkClientSecure.new", NetworkClientSecure_new, PUSH new NetworkClientSecure()) \
XV(HTTPClient, "NetworkClientSecure.delete", NetworkClientSecure_delete, delete ((NetworkClientSecure *) a0); DROP) \
XV(HTTPClient, "NetworkClientSecure.setCACert", NetworkClientSecure_setCACert, \
((NetworkClientSecure *) a0)->setCACert(c1); DROPn(2)) \
XV(HTTPClient, "HTTPClient.new", HTTPClient_new, PUSH new HTTPClient()) \
XV(HTTPClient, "HTTPClient.delete", HTTPClient_delete, delete (HTTPClient *) a0; DROP) \
XV(HTTPClient, "HTTPClient.begin", HTTPClient_begin, n0 = ((HTTPClient *) a0)->begin(c1); NIP) \
XV(HTTPClient, "HTTPClient.beginNC", HTTPClient_beginNC, \
n0 = ((HTTPClient *) a0)->begin(*(NetworkClient *)a1, c2); NIPn(2)) \
XV(HTTPClient, "HTTPClient.end", HTTPClient_end, ((HTTPClient *) a0)->end(); DROP) \
XV(HTTPClient, "HTTPClient.connected", HTTPClient_connected, n0 = ((HTTPClient *) a0)->connected()) \
XV(HTTPClient, "HTTPClient.setReuse", HTTPClient_setReuse, ((HTTPClient *) a0)->setReuse(n1); DROPn(2)) \
XV(HTTPClient, "HTTPClient.setUserAgent", HTTPClient_setUserAgent, ((HTTPClient *) a0)->setUserAgent(c1); DROPn(2)) \
XV(HTTPClient, "HTTPClient.setAuthorization", HTTPClient_setAuthorization, \
((HTTPClient *) a0)->setAuthorization(c2, c1); DROPn(3)) \
XV(HTTPClient, "HTTPClient.setFollowRedirects", HTTPClient_setFollowRedirects, \
((HTTPClient *) a0)->setFollowRedirects((followRedirects_t) n1); DROPn(2)) \
XV(HTTPClient, "HTTPClient.setRedirectLimit", HTTPClient_setRedirectLimit, \
((HTTPClient *) a0)->setRedirectLimit(n1); DROPn(2)) \
XV(HTTPClient, "HTTPClient.GET", HTTPClient_GET, n0 = ((HTTPClient *) a0)->GET()) \
XV(HTTPClient, "HTTPClient.POST", HTTPClient_POST, n0 = ((HTTPClient *) a0)->POST(b2, n1); NIPn(2)) \
XV(HTTPClient, "HTTPClient.addHeader", HTTPClient_addHeader, ((HTTPClient *) a0)->addHeader(c2, c1); DROPn(3)) \
XV(HTTPClient, "HTTPClient.sendRequest", HTTPClient_sendRequest, n0 = ((HTTPClient *) a0)->sendRequest(c3, b2, n1); NIPn(3)) \
XV(HTTPClient, "HTTPClient.getSize", HTTPClient_getSize, n0 = ((HTTPClient *) a0)->getSize()) \
XV(HTTPClient, "HTTPClient.getString", HTTPClient_getString, ((HTTPClient *) a0)->getString().getBytes(b2, n1); DROPn(3)) \
XV(HTTPClient, "HTTPClient.getStreamPtr", HTTPClient_getStreamPtr, \
NetworkClient *s = ((HTTPClient *) a0)->getStreamPtr(); n0 = (cell_t) s) \
XV(HTTPClient, "NetworkClient.available", NetworkClient_available, n0 = ((NetworkClient *) a0)->available()) \
XV(HTTPClient, "NetworkClient.readBytes", NetworkClient_readBytes, n0 = ((NetworkClient *) a0)->readBytes(b2, n1); NIPn(2))

View File

@ -0,0 +1,37 @@
\ Copyright 2023 Bradley D. Nelson
\
\ Licensed under the Apache License, Version 2.0 (the "License");
\ you may not use this file except in compliance with the License.
\ You may obtain a copy of the License at
\
\ http://www.apache.org/licenses/LICENSE-2.0
\
\ Unless required by applicable law or agreed to in writing, software
\ distributed under the License is distributed on an "AS IS" BASIS,
\ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
\ See the License for the specific language governing permissions and
\ limitations under the License.
vocabulary interrupts interrupts definitions
transfer interrupts-builtins
DEFINED? gpio_config [IF]
0 constant ESP_INTR_FLAG_DEFAULT
: ESP_INTR_FLAG_LEVELn ( n=1-6 -- n ) 1 swap lshift ;
1 7 lshift constant ESP_INTR_FLAG_NMI
1 8 lshift constant ESP_INTR_FLAG_SHARED
1 9 lshift constant ESP_INTR_FLAG_EDGE
1 10 lshift constant ESP_INTR_FLAG_IRAM
1 11 lshift constant ESP_INTR_FLAG_INTRDISABLED
( Prefix these with # because GPIO_INTR_DISABLE conflicts with a function. )
0 constant #GPIO_INTR_DISABLE
1 constant #GPIO_INTR_POSEDGE
2 constant #GPIO_INTR_NEGEDGE
3 constant #GPIO_INTR_ANYEDGE
4 constant #GPIO_INTR_LOW_LEVEL
5 constant #GPIO_INTR_HIGH_LEVEL
( Easy word to trigger on any change to a pin )
ESP_INTR_FLAG_DEFAULT gpio_install_isr_service drop
: pinchange ( xt pin ) dup #GPIO_INTR_ANYEDGE gpio_set_intr_type throw
swap 0 gpio_isr_handler_add throw ;
[THEN]
forth definitions

View File

@ -0,0 +1,157 @@
// Copyright 2023 Bradley D. Nelson
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/*
* ESP32forth Interrupts v{{VERSION}}
* Revision: {{REVISION}}
*/
#define INTERRUPT_STACK_CELLS 64
#include "esp_intr_alloc.h"
#include "driver/timer.h"
#include "driver/gpio.h"
static cell_t EspIntrAlloc(cell_t source, cell_t flags, cell_t xt, cell_t arg, void *ret);
static cell_t GpioIsrHandlerAdd(cell_t pin, cell_t xt, cell_t arg);
static cell_t TimerIsrCallbackAdd(cell_t group, cell_t timer, cell_t xt, cell_t arg, cell_t flags);
static void TimerInitNull(cell_t group, cell_t timer);
#define OPTIONAL_INTERRUPTS_VOCABULARIES V(interrupts) V(timers)
#define OPTIONAL_INTERRUPTS_SUPPORT \
XV(internals, "interrupts-source", INTERRUPTS_SOURCE, \
PUSH interrupts_source; PUSH sizeof(interrupts_source) - 1) \
YV(interrupts, gpio_config, n0 = gpio_config((const gpio_config_t *) a0)) \
YV(interrupts, gpio_reset_pin, n0 = gpio_reset_pin((gpio_num_t) n0)) \
YV(interrupts, gpio_set_intr_type, n0 = gpio_set_intr_type((gpio_num_t) n1, (gpio_int_type_t) n0); NIP) \
YV(interrupts, gpio_intr_enable, n0 = gpio_intr_enable((gpio_num_t) n0)) \
YV(interrupts, gpio_intr_disable, n0 = gpio_intr_disable((gpio_num_t) n0)) \
YV(interrupts, gpio_set_level, n0 = gpio_set_level((gpio_num_t) n1, n0); NIP) \
YV(interrupts, gpio_get_level, n0 = gpio_get_level((gpio_num_t) n0)) \
YV(interrupts, gpio_set_direction, n0 = gpio_set_direction((gpio_num_t) n1, (gpio_mode_t) n0); NIP) \
YV(interrupts, gpio_set_pull_mode, n0 = gpio_set_pull_mode((gpio_num_t) n1, (gpio_pull_mode_t) n0); NIP) \
YV(interrupts, gpio_wakeup_enable, n0 = gpio_wakeup_enable((gpio_num_t) n1, (gpio_int_type_t) n0); NIP) \
YV(interrupts, gpio_wakeup_disable, n0 = gpio_wakeup_disable((gpio_num_t) n0)) \
YV(interrupts, gpio_pullup_en, n0 = gpio_pullup_en((gpio_num_t) n0)) \
YV(interrupts, gpio_pullup_dis, n0 = gpio_pullup_dis((gpio_num_t) n0)) \
YV(interrupts, gpio_pulldown_en, n0 = gpio_pulldown_en((gpio_num_t) n0)) \
YV(interrupts, gpio_pulldown_dis, n0 = gpio_pulldown_dis((gpio_num_t) n0)) \
YV(interrupts, gpio_hold_en, n0 = gpio_hold_en((gpio_num_t) n0)) \
YV(interrupts, gpio_hold_dis, n0 = gpio_hold_dis((gpio_num_t) n0)) \
YV(interrupts, gpio_deep_sleep_hold_en, gpio_deep_sleep_hold_en()) \
YV(interrupts, gpio_deep_sleep_hold_dis, gpio_deep_sleep_hold_dis()) \
YV(interrupts, gpio_install_isr_service, n0 = gpio_install_isr_service(n0)) \
YV(interrupts, gpio_uninstall_isr_service, gpio_uninstall_isr_service()) \
YV(interrupts, gpio_isr_handler_add, n0 = GpioIsrHandlerAdd(n2, n1, n0); NIPn(2)) \
YV(interrupts, gpio_isr_handler_remove, n0 = gpio_isr_handler_remove((gpio_num_t) n0)) \
YV(interrupts, gpio_set_drive_capability, n0 = gpio_set_drive_capability((gpio_num_t) n1, (gpio_drive_cap_t) n0); NIP) \
YV(interrupts, gpio_get_drive_capability, n0 = gpio_get_drive_capability((gpio_num_t) n1, (gpio_drive_cap_t *) a0); NIP) \
YV(interrupts, esp_intr_alloc, n0 = EspIntrAlloc(n4, n3, n2, n1, a0); NIPn(4)) \
YV(interrupts, esp_intr_free, n0 = esp_intr_free((intr_handle_t) n0)) \
YV(timers, timer_isr_callback_add, n0 = TimerIsrCallbackAdd(n4, n3, n2, n1, n0); NIPn(4)) \
YV(timers, timer_init_null, TimerInitNull(n1, n0); DROPn(2)) \
YV(timers, timer_get_counter_value, \
n0 = timer_get_counter_value((timer_group_t) n2, (timer_idx_t) n1, \
(uint64_t *) a0); NIPn(2)) \
YV(timers, timer_set_counter_value, \
uint64_t val = *(uint64_t *) a0; \
n0 = timer_set_counter_value((timer_group_t) n2, (timer_idx_t) n1, val); NIPn(2)) \
YV(timers, timer_start, \
n0 = timer_start((timer_group_t) n1, (timer_idx_t) n0); NIP) \
YV(timers, timer_pause, \
n0 = timer_pause((timer_group_t) n1, (timer_idx_t) n0); NIP) \
YV(timers, timer_set_counter_mode, \
n0 = timer_set_counter_mode((timer_group_t) n2, (timer_idx_t) n1, \
(timer_count_dir_t) n0); NIPn(2)) \
YV(timers, timer_set_auto_reload, \
n0 = timer_set_auto_reload((timer_group_t) n2, (timer_idx_t) n1, \
(timer_autoreload_t) n0); NIPn(2)) \
YV(timers, timer_set_divider, \
n0 = timer_set_divider((timer_group_t) n2, (timer_idx_t) n1, n0); NIPn(2)) \
YV(timers, timer_set_alarm_value, uint64_t val = *(uint64_t *) a0; \
n0 = timer_set_alarm_value((timer_group_t) n2, (timer_idx_t) n1, val); NIPn(2)) \
YV(timers, timer_get_alarm_value, \
n0 = timer_get_alarm_value((timer_group_t) n2, (timer_idx_t) n1, \
(uint64_t *) a0); NIPn(2)) \
YV(timers, timer_set_alarm, \
n0 = timer_set_alarm((timer_group_t) n2, (timer_idx_t) n1, \
(timer_alarm_t) n0); NIPn(2)) \
YV(timers, timer_group_intr_enable, \
n0 = timer_group_intr_enable((timer_group_t) n1, (timer_intr_t) n0); NIP) \
YV(timers, timer_group_intr_disable, \
n0 = timer_group_intr_disable((timer_group_t) n1, (timer_intr_t) n0); NIP) \
YV(timers, timer_enable_intr, \
n0 = timer_enable_intr((timer_group_t) n1, (timer_idx_t) n0); NIP) \
YV(timers, timer_disable_intr, \
n0 = timer_disable_intr((timer_group_t) n1, (timer_idx_t) n0); NIP)
struct handle_interrupt_args {
cell_t xt;
cell_t arg;
};
static void IRAM_ATTR HandleInterrupt(void *arg) {
struct handle_interrupt_args *args = (struct handle_interrupt_args *) arg;
cell_t code[2];
code[0] = args->xt;
code[1] = g_sys->YIELD_XT;
cell_t fstack[INTERRUPT_STACK_CELLS];
cell_t rstack[INTERRUPT_STACK_CELLS];
cell_t stack[INTERRUPT_STACK_CELLS];
stack[0] = args->arg;
cell_t *rp = rstack;
*++rp = (cell_t) code;
*++rp = (cell_t) (fstack + 1);
*++rp = (cell_t) (stack + 1);
forth_run(rp);
}
static bool IRAM_ATTR HandleInterruptAndRet(void *arg) {
HandleInterrupt(arg);
return true;
}
static cell_t EspIntrAlloc(cell_t source, cell_t flags, cell_t xt, cell_t arg, void *ret) {
// NOTE: Leaks memory.
struct handle_interrupt_args *args = (struct handle_interrupt_args *) malloc(sizeof(struct handle_interrupt_args));
args->xt = xt;
args->arg = arg;
return esp_intr_alloc(source, flags, HandleInterrupt, args, (intr_handle_t *) ret);
}
static cell_t GpioIsrHandlerAdd(cell_t pin, cell_t xt, cell_t arg) {
// NOTE: Leaks memory.
struct handle_interrupt_args *args = (struct handle_interrupt_args *) malloc(sizeof(struct handle_interrupt_args));
args->xt = xt;
args->arg = arg;
return gpio_isr_handler_add((gpio_num_t) pin, HandleInterrupt, args);
}
static void TimerInitNull(cell_t group, cell_t timer) {
// Seems to be required starting in the 2.0 IDE.
timer_config_t config;
memset(&config, 0, sizeof(config));
config.divider = 2;
timer_init((timer_group_t) group, (timer_idx_t) timer, &config);
}
static cell_t TimerIsrCallbackAdd(cell_t group, cell_t timer, cell_t xt, cell_t arg, cell_t flags) {
// NOTE: Leaks memory.
struct handle_interrupt_args *args = (struct handle_interrupt_args *) malloc(sizeof(struct handle_interrupt_args));
args->xt = xt;
args->arg = arg;
return timer_isr_callback_add((timer_group_t) group, (timer_idx_t) timer, HandleInterruptAndRet, args, flags);
}
#include "gen/esp32_interrupts.h"

View File

@ -0,0 +1,69 @@
\ Copyright 2021 Bradley D. Nelson
\
\ Licensed under the Apache License, Version 2.0 (the "License");
\ you may not use this file except in compliance with the License.
\ You may obtain a copy of the License at
\
\ http://www.apache.org/licenses/LICENSE-2.0
\
\ Unless required by applicable law or agreed to in writing, software
\ distributed under the License is distributed on an "AS IS" BASIS,
\ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
\ See the License for the specific language governing permissions and
\ limitations under the License.
needs interrupts.fs
internals definitions
transfer timers-builtins
forth definitions
( Lazy loaded timers )
: timers r|
vocabulary timers timers definitions
also registers also interrupts also internals
transfer timers-builtins
( Initialize all timers, to mimic pre-2.0 behavior. )
0 0 timer_init_null
0 1 timer_init_null
1 0 timer_init_null
1 1 timer_init_null
( 0-4 -> two cells )
: t>nx ( t -- n x ) dup 2/ 1 and swap 1 and ;
create tmp 2 cells allot
: timer@ ( t -- lo hi ) t>nx tmp timer_get_counter_value throw tmp 2@ ;
: timer! ( lo hi t -- ) >r tmp 2! r> t>nx tmp timer_set_counter_value throw ;
: alarm@ ( t -- lo hi ) t>nx tmp timer_get_alarm_value throw tmp 2@ ;
: alarm! ( lo hi t -- ) >r tmp 2! r> t>nx tmp timer_set_alarm_value throw ;
: enable! ( v t )
swap >r t>nx r> if timer_start else timer_pause then throw ;
: increase! ( v t ) swap >r t>nx r> timer_set_counter_mode throw ;
: autoreload! ( v t ) swap >r t>nx r> timer_set_auto_reload throw ;
: divider! ( v t ) swap >r t>nx r> timer_set_divider throw ;
: alarm-enable! ( v t ) swap >r t>nx r> timer_set_alarm throw ;
: int-enable! ( f t -- )
swap >r t>nx r> if timer_enable_intr else timer_disable_intr then throw ;
: onalarm ( xt t ) swap >r t>nx r>
0 ESP_INTR_FLAG_EDGE timer_isr_callback_add throw ;
: interval ( xt usec t ) 0 over enable!
0 over int-enable!
80 over divider!
swap over 0 swap alarm!
dup >r onalarm r>
dup >r 0 0 r> timer!
1 over increase!
1 over autoreload!
1 over alarm-enable!
1 over int-enable!
1 swap enable! ;
only forth definitions
timers
| evaluate ;

View File

@ -0,0 +1,37 @@
\ Copyright 2023 Bradley D. Nelson
\
\ Licensed under the Apache License, Version 2.0 (the "License");
\ you may not use this file except in compliance with the License.
\ You may obtain a copy of the License at
\
\ http://www.apache.org/licenses/LICENSE-2.0
\
\ Unless required by applicable law or agreed to in writing, software
\ distributed under the License is distributed on an "AS IS" BASIS,
\ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
\ See the License for the specific language governing permissions and
\ limitations under the License.
vocabulary oled oled definitions
transfer oled-builtins
DEFINED? OledNew [IF]
128 constant WIDTH
64 constant HEIGHT
-1 constant OledReset
0 constant BLACK
1 constant WHITE
1 constant SSD1306_EXTERNALVCC
2 constant SSD1306_SWITCHCAPVCC
: OledInit
OledAddr @ 0= if
WIDTH HEIGHT OledReset OledNew
SSD1306_SWITCHCAPVCC $3C OledBegin drop
then
OledCLS
2 OledTextsize ( Draw 2x Scale Text )
WHITE OledTextc ( Draw white text )
0 0 OledSetCursor ( Start at top-left corner )
z" *Esp32forth*" OledPrintln OledDisplay
;
[THEN]
forth definitions

View File

@ -0,0 +1,58 @@
// Copyright 2023 Bradley D. Nelson
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/*
* ESP32forth Oled v{{VERSION}}
* Revision: {{REVISION}}
*/
// You will need to install these libraries from the Library Manager:
// Adafruit SSD1306
// Adafruit GFX Library
// Adafruit BusIO
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
static Adafruit_SSD1306 *oled_display = 0;
#define OPTIONAL_OLED_VOCABULARY V(oled)
#define OPTIONAL_OLED_SUPPORT \
XV(internals, "oled-source", OLED_SOURCE, \
PUSH oled_source; PUSH sizeof(oled_source) - 1) \
YV(oled, OledAddr, PUSH &oled_display) \
YV(oled, OledNew, oled_display = new Adafruit_SSD1306(n2, n1, &Wire, n0); DROPn(3)) \
YV(oled, OledDelete, delete oled_display) \
YV(oled, OledBegin, n0 = oled_display->begin(n1, n0); NIP) \
YV(oled, OledHOME, oled_display->setCursor(0,0); DROP) \
YV(oled, OledCLS, oled_display->clearDisplay()) \
YV(oled, OledTextc, oled_display->setTextColor(n0); DROP) \
YV(oled, OledPrintln, oled_display->println(c0); DROP) \
YV(oled, OledNumln, oled_display->println(n0); DROP) \
YV(oled, OledNum, oled_display->print(n0); DROP) \
YV(oled, OledDisplay, oled_display->display()) \
YV(oled, OledPrint, oled_display->write(c0); DROP) \
YV(oled, OledInvert, oled_display->invertDisplay(n0); DROP) \
YV(oled, OledTextsize, oled_display->setTextSize(n0); DROP) \
YV(oled, OledSetCursor, oled_display->setCursor(n1,n0); DROPn(2)) \
YV(oled, OledPixel, oled_display->drawPixel(n2, n1, n0); DROPn(2)) \
YV(oled, OledDrawL, oled_display->drawLine(n4, n3, n2, n1, n0); DROPn(4)) \
YV(oled, OledCirc, oled_display->drawCircle(n3,n2, n1, n0); DROPn(3)) \
YV(oled, OledCircF, oled_display->fillCircle(n3, n2, n1, n0); DROPn(3)) \
YV(oled, OledRect, oled_display->drawRect(n4, n3, n2, n1, n0); DROPn(4)) \
YV(oled, OledRectF, oled_display->fillRect(n4, n3, n2, n1, n0); DROPn(3)) \
YV(oled, OledRectR, oled_display->drawRoundRect(n5, n4, n3, n2, n1, n0); DROPn(5)) \
YV(oled, OledRectRF, oled_display->fillRoundRect(n5, n4, n3, n2, n1, n0 ); DROPn(5))
#include "gen/esp32_oled.h"

74
esp32/optional/rmt.h Normal file
View File

@ -0,0 +1,74 @@
// Copyright 2023 Bradley D. Nelson
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/*
* ESP32forth RMT v{{VERSION}}
* Revision: {{REVISION}}
*/
#include "driver/rmt.h"
#define OPTIONAL_RMT_VOCABULARY V(rmt)
#define OPTIONAL_RMT_SUPPORT \
YV(rmt, rmt_set_clk_div, n0 = rmt_set_clk_div((rmt_channel_t) n1, n0); NIP) \
YV(rmt, rmt_get_clk_div, n0 = rmt_get_clk_div((rmt_channel_t) n1, b0); NIP) \
YV(rmt, rmt_set_rx_idle_thresh, n0 = rmt_set_rx_idle_thresh((rmt_channel_t) n1, n0); NIP) \
YV(rmt, rmt_get_rx_idle_thresh, \
n0 = rmt_get_rx_idle_thresh((rmt_channel_t) n1, (uint16_t *) a0); NIP) \
YV(rmt, rmt_set_mem_block_num, n0 = rmt_set_mem_block_num((rmt_channel_t) n1, n0); NIP) \
YV(rmt, rmt_get_mem_block_num, n0 = rmt_get_mem_block_num((rmt_channel_t) n1, b0); NIP) \
YV(rmt, rmt_set_tx_carrier, n0 = rmt_set_tx_carrier((rmt_channel_t) n4, n3, n2, n1, \
(rmt_carrier_level_t) n0); NIPn(4)) \
YV(rmt, rmt_set_mem_pd, n0 = rmt_set_mem_pd((rmt_channel_t) n1, n0); NIP) \
YV(rmt, rmt_get_mem_pd, n0 = rmt_get_mem_pd((rmt_channel_t) n1, (bool *) a0); NIP) \
YV(rmt, rmt_tx_start, n0 = rmt_tx_start((rmt_channel_t) n1, n0); NIP) \
YV(rmt, rmt_tx_stop, n0 = rmt_tx_stop((rmt_channel_t) n0)) \
YV(rmt, rmt_rx_start, n0 = rmt_rx_start((rmt_channel_t) n1, n0); NIP) \
YV(rmt, rmt_rx_stop, n0 = rmt_rx_stop((rmt_channel_t) n0)) \
YV(rmt, rmt_tx_memory_reset, n0 = rmt_tx_memory_reset((rmt_channel_t) n0)) \
YV(rmt, rmt_rx_memory_reset, n0 = rmt_rx_memory_reset((rmt_channel_t) n0)) \
YV(rmt, rmt_set_memory_owner, n0 = rmt_set_memory_owner((rmt_channel_t) n1, (rmt_mem_owner_t) n0); NIP) \
YV(rmt, rmt_get_memory_owner, n0 = rmt_get_memory_owner((rmt_channel_t) n1, (rmt_mem_owner_t *) a0); NIP) \
YV(rmt, rmt_set_tx_loop_mode, n0 = rmt_set_tx_loop_mode((rmt_channel_t) n1, n0); NIP) \
YV(rmt, rmt_get_tx_loop_mode, n0 = rmt_get_tx_loop_mode((rmt_channel_t) n1, (bool *) a0); NIP) \
YV(rmt, rmt_set_rx_filter, n0 = rmt_set_rx_filter((rmt_channel_t) n2, n1, n0); NIPn(2)) \
YV(rmt, rmt_set_source_clk, n0 = rmt_set_source_clk((rmt_channel_t) n1, (rmt_source_clk_t) n0); NIP) \
YV(rmt, rmt_get_source_clk, n0 = rmt_get_source_clk((rmt_channel_t) n1, (rmt_source_clk_t * ) a0); NIP) \
YV(rmt, rmt_set_idle_level, n0 = rmt_set_idle_level((rmt_channel_t) n2, n1, \
(rmt_idle_level_t) n0); NIPn(2)) \
YV(rmt, rmt_get_idle_level, n0 = rmt_get_idle_level((rmt_channel_t) n2, \
(bool *) a1, (rmt_idle_level_t *) a0); NIPn(2)) \
YV(rmt, rmt_get_status, n0 = rmt_get_status((rmt_channel_t) n1, (uint32_t *) a0); NIP) \
YV(rmt, rmt_set_rx_intr_en, n0 = rmt_set_rx_intr_en((rmt_channel_t) n1, n0); NIP) \
YV(rmt, rmt_set_err_intr_en, n0 = rmt_set_err_intr_en((rmt_channel_t) n1, (rmt_mode_t) n0); NIP) \
YV(rmt, rmt_set_tx_intr_en, n0 = rmt_set_tx_intr_en((rmt_channel_t) n1, n0); NIP) \
YV(rmt, rmt_set_tx_thr_intr_en, n0 = rmt_set_tx_thr_intr_en((rmt_channel_t) n2, n1, n0); NIPn(2)) \
YV(rmt, rmt_set_gpio, n0 = rmt_set_gpio((rmt_channel_t) n3, (rmt_mode_t) n2, (gpio_num_t) n1, n0); NIPn(3)) \
YV(rmt, rmt_config, n0 = rmt_config((const rmt_config_t *) a0)) \
YV(rmt, rmt_isr_register, n0 = rmt_isr_register((void (*)(void*)) a3, a2, n1, \
(rmt_isr_handle_t *) a0); NIPn(3)) \
YV(rmt, rmt_isr_deregister, n0 = rmt_isr_deregister((rmt_isr_handle_t) n0)) \
YV(rmt, rmt_fill_tx_items, n0 = rmt_fill_tx_items((rmt_channel_t) n3, \
(rmt_item32_t *) a2, n1, n0); NIPn(3)) \
YV(rmt, rmt_driver_install, n0 = rmt_driver_install((rmt_channel_t) n2, n1, n0); NIPn(2)) \
YV(rmt, rmt_driver_uinstall, n0 = rmt_driver_uninstall((rmt_channel_t) n0)) \
YV(rmt, rmt_get_channel_status, n0 = rmt_get_channel_status((rmt_channel_status_result_t *) a0)) \
YV(rmt, rmt_get_counter_clock, n0 = rmt_get_counter_clock((rmt_channel_t) n1, (uint32_t *) a0); NIP) \
YV(rmt, rmt_write_items, n0 = rmt_write_items((rmt_channel_t) n3, (rmt_item32_t *) a2, n1, n0); NIPn(3)) \
YV(rmt, rmt_wait_tx_done, n0 = rmt_wait_tx_done((rmt_channel_t) n1, n0); NIP) \
YV(rmt, rmt_get_ringbuf_handle, n0 = rmt_get_ringbuf_handle((rmt_channel_t) n1, (RingbufHandle_t *) a0); NIP) \
YV(rmt, rmt_translator_init, n0 = rmt_translator_init((rmt_channel_t) n1, (sample_to_rmt_t) n0); NIP) \
YV(rmt, rmt_translator_set_context, n0 = rmt_translator_set_context((rmt_channel_t) n1, a0); NIP) \
YV(rmt, rmt_translator_get_context, n0 = rmt_translator_get_context((const size_t *) a1, (void **) a0); NIP) \
YV(rmt, rmt_write_sample, n0 = rmt_write_sample((rmt_channel_t) n3, b2, n1, n0); NIPn(3))

View File

@ -0,0 +1,40 @@
\ Copyright 2021 Bradley D. Nelson
\
\ Licensed under the Apache License, Version 2.0 (the "License");
\ you may not use this file except in compliance with the License.
\ You may obtain a copy of the License at
\
\ http://www.apache.org/licenses/LICENSE-2.0
\
\ Unless required by applicable law or agreed to in writing, software
\ distributed under the License is distributed on an "AS IS" BASIS,
\ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
\ See the License for the specific language governing permissions and
\ limitations under the License.
DEFINED? bluetooth [IF]
( Lazy loaded Bluetooth Serial Terminal )
: bterm r|
vocabulary bterm bterm definitions
also bluetooth also internals also esp
120000 getFreeHeap - 0 max relinquish ( must have 110k for bluetooth )
z" forth xx:xx:xx:xx:xx:xx" constant name
( Create unique name for device )
base @ hex getEfuseMac
<# # # char : hold # # #> name 6 + swap cmove
<# # # char : hold # # char : hold # # char : hold # # #> name c + swap cmove
base !
SerialBT.new constant bt
name 0 bt SerialBT.begin drop
." Bluetooth Serial Terminal on: " name z>s type cr
: bt-type ( a n -- ) bt SerialBT.write drop ;
: bt-key? ( -- f ) bt SerialBT.available 0<> pause ;
: bt-key ( -- ch ) begin bt-key? until 0 >r rp@ 1 bt SerialBT.readBytes drop r> ;
: bt-on ['] bt-type is type ['] bt-key is key ['] bt-key? is key? ;
: bt-off ['] default-type is type ['] default-key is key ['] default-key? is key? ;
only forth definitions
bterm 500 ms bt-on
| evaluate ;
[THEN]

View File

@ -0,0 +1,25 @@
\ Copyright 2023 Bradley D. Nelson
\
\ Licensed under the Apache License, Version 2.0 (the "License");
\ you may not use this file except in compliance with the License.
\ You may obtain a copy of the License at
\
\ http://www.apache.org/licenses/LICENSE-2.0
\
\ Unless required by applicable law or agreed to in writing, software
\ distributed under the License is distributed on an "AS IS" BASIS,
\ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
\ See the License for the specific language governing permissions and
\ limitations under the License.
needs bterm.fs
DEFINED? SerialBT.new [IF]
vocabulary bluetooth bluetooth definitions
transfer bluetooth-builtins
forth definitions
[ELSE]
internals definitions
transfer bluetooth-builtins
forth definitions
[THEN]

View File

@ -0,0 +1,55 @@
// Copyright 2022 Bradley D. Nelson
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/*
* ESP32forth Serial Bluetooth v{{VERSION}}
* Revision: {{REVISION}}
*/
#include "esp_bt_device.h"
#include "BluetoothSerial.h"
#define bt0 ((BluetoothSerial *) a0)
#if defined(CONFIG_IDF_TARGET_ESP32S3)
# define BT0_ENABLE_SSP
#else
# define BT0_ENABLE_SSP bt0->enableSSP()
#endif
#define OPTIONAL_BLUETOOTH_VOCABULARY V(bluetooth)
#define OPTIONAL_SERIAL_BLUETOOTH_SUPPORT \
XV(internals, "serial-bluetooth-source", SERIAL_BLUETOOTH_SOURCE, \
PUSH serial_bluetooth_source; PUSH sizeof(serial_bluetooth_source) - 1) \
XV(bluetooth, "SerialBT.new", SERIALBT_NEW, PUSH new BluetoothSerial()) \
XV(bluetooth, "SerialBT.delete", SERIALBT_DELETE, delete bt0; DROP) \
XV(bluetooth, "SerialBT.begin", SERIALBT_BEGIN, n0 = bt0->begin(c2, n1); NIPn(2)) \
XV(bluetooth, "SerialBT.end", SERIALBT_END, bt0->end(); DROP) \
XV(bluetooth, "SerialBT.available", SERIALBT_AVAILABLE, n0 = bt0->available()) \
XV(bluetooth, "SerialBT.readBytes", SERIALBT_READ_BYTES, n0 = bt0->readBytes(b2, n1); NIPn(2)) \
XV(bluetooth, "SerialBT.write", SERIALBT_WRITE, n0 = bt0->write(b2, n1); NIPn(2)) \
XV(bluetooth, "SerialBT.flush", SERIALBT_FLUSH, bt0->flush(); DROP) \
XV(bluetooth, "SerialBT.hasClient", SERIALBT_HAS_CLIENT, n0 = bt0->hasClient()) \
XV(bluetooth, "SerialBT.enableSSP", SERIALBT_ENABLE_SSP, BT0_ENABLE_SSP; DROP) \
XV(bluetooth, "SerialBT.setPin", SERIALBT_SET_PIN, n0 = bt0->setPin(c1); NIP) \
XV(bluetooth, "SerialBT.unpairDevice", SERIALBT_UNPAIR_DEVICE, \
n0 = bt0->unpairDevice(b1); NIP) \
XV(bluetooth, "SerialBT.connect", SERIALBT_CONNECT, n0 = bt0->connect(c1); NIP) \
XV(bluetooth, "SerialBT.connectAddr", SERIALBT_CONNECT_ADDR, n0 = bt0->connect(b1); NIP) \
XV(bluetooth, "SerialBT.disconnect", SERIALBT_DISCONNECT, n0 = bt0->disconnect()) \
XV(bluetooth, "SerialBT.connected", SERIALBT_CONNECTED, n0 = bt0->connected(n1); NIP) \
XV(bluetooth, "SerialBT.isReady", SERIALBT_IS_READY, n0 = bt0->isReady(n2, n1); NIPn(2)) \
/* Bluetooth */ \
YV(bluetooth, esp_bt_dev_get_address, PUSH esp_bt_dev_get_address())
#include "gen/esp32_serial-bluetooth.h"

View File

@ -0,0 +1,45 @@
\ Copyright 2023 Bradley D. Nelson
\
\ Licensed under the Apache License, Version 2.0 (the "License");
\ you may not use this file except in compliance with the License.
\ You may obtain a copy of the License at
\
\ http://www.apache.org/licenses/LICENSE-2.0
\
\ Unless required by applicable law or agreed to in writing, software
\ distributed under the License is distributed on an "AS IS" BASIS,
\ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
\ See the License for the specific language governing permissions and
\ limitations under the License.
vocabulary spi_flash spi_flash definitions
transfer spi_flash-builtins
DEFINED? spi_flash_init [IF]
0 constant SPI_PARTITION_TYPE_APP
1 constant SPI_PARTITION_TYPE_DATA
$ff constant SPI_PARTITION_SUBTYPE_ANY
also structures
struct esp_partition_t
( Work around changing struct layout )
esp_partition_t_size 40 >= [IF]
ptr field p>gap
[THEN]
ptr field p>type
ptr field p>subtype
ptr field p>address
ptr field p>size
ptr field p>label
: p. ( part -- )
base @ >r >r decimal
." TYPE: " r@ p>type @ . ." SUBTYPE: " r@ p>subtype @ .
." ADDR: " r@ hex p>address @ . ." SIZE: " r@ p>size @ .
." LABEL: " r> p>label @ z>s type cr r> base ! ;
: list-partition-type ( type -- )
SPI_PARTITION_SUBTYPE_ANY 0 esp_partition_find
begin dup esp_partition_get p. esp_partition_next dup 0= until drop ;
: list-partitions SPI_PARTITION_TYPE_APP list-partition-type
SPI_PARTITION_TYPE_DATA list-partition-type ;
[THEN]
only forth definitions

View File

@ -0,0 +1,80 @@
// Copyright 2023 Bradley D. Nelson
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/*
* ESP32forth SPI Flash v{{VERSION}}
* Revision: {{REVISION}}
*/
#include "esp_spi_flash.h"
#include "esp_partition.h"
#define OPTIONAL_SPI_FLASH_VOCABULARY V(spi_flash)
#define OPTIONAL_SPI_FLASH_SUPPORT \
XV(internals, "spi-flash-source", SPI_FLASH_SOURCE, \
PUSH spi_flash_source; PUSH sizeof(spi_flash_source) - 1) \
YV(spi_flash, spi_flash_init, spi_flash_init()) \
YV(spi_flash, spi_flash_get_chip_size, PUSH spi_flash_get_chip_size()) \
YV(spi_flash, spi_flash_erase_sector, n0 = spi_flash_erase_sector(n0)) \
YV(spi_flash, spi_flash_erase_range, n0 = spi_flash_erase_range(n1, n0); DROP) \
YV(spi_flash, spi_flash_write, n0 = spi_flash_write(n2, a1, n0); NIPn(2)) \
YV(spi_flash, spi_flash_write_encrypted, n0 = spi_flash_write_encrypted(n2, a1, n0); NIPn(2)) \
YV(spi_flash, spi_flash_read, n0 = spi_flash_read(n2, a1, n0); NIPn(2)) \
YV(spi_flash, spi_flash_read_encrypted, n0 = spi_flash_read_encrypted(n2, a1, n0); NIPn(2)) \
YV(spi_flash, spi_flash_mmap, \
n0 = spi_flash_mmap(n4, n3, (spi_flash_mmap_memory_t) n2, \
(const void **) a1, (spi_flash_mmap_handle_t *) a0); NIPn(4)) \
YV(spi_flash, spi_flash_mmap_pages, \
n0 = spi_flash_mmap_pages((const int *) a4, n3, (spi_flash_mmap_memory_t) n2, \
(const void **) a1, (spi_flash_mmap_handle_t *) a0); NIPn(4)) \
YV(spi_flash, spi_flash_munmap, spi_flash_munmap((spi_flash_mmap_handle_t) a0); DROP) \
YV(spi_flash, spi_flash_mmap_dump, spi_flash_mmap_dump()) \
YV(spi_flash, spi_flash_mmap_get_free_pages, \
n0 = spi_flash_mmap_get_free_pages((spi_flash_mmap_memory_t) n0)) \
YV(spi_flash, spi_flash_cache2phys, n0 = spi_flash_cache2phys(a0)) \
YV(spi_flash, spi_flash_phys2cache, \
n0 = (cell_t) spi_flash_phys2cache(n1, (spi_flash_mmap_memory_t) n0); NIP) \
YV(spi_flash, spi_flash_cache_enabled, PUSH spi_flash_cache_enabled()) \
YV(spi_flash, esp_partition_find, \
n0 = (cell_t) esp_partition_find((esp_partition_type_t) n2, \
(esp_partition_subtype_t) n1, c0); NIPn(2)) \
YV(spi_flash, esp_partition_find_first, \
n0 = (cell_t) esp_partition_find_first((esp_partition_type_t) n2, \
(esp_partition_subtype_t) n1, c0); NIPn(2)) \
YV(spi_flash, esp_partition_t_size, PUSH sizeof(esp_partition_t)) \
YV(spi_flash, esp_partition_get, \
n0 = (cell_t) esp_partition_get((esp_partition_iterator_t) a0)) \
YV(spi_flash, esp_partition_next, \
n0 = (cell_t) esp_partition_next((esp_partition_iterator_t) a0)) \
YV(spi_flash, esp_partition_iterator_release, \
esp_partition_iterator_release((esp_partition_iterator_t) a0); DROP) \
YV(spi_flash, esp_partition_verify, n0 = (cell_t) esp_partition_verify((esp_partition_t *) a0)) \
YV(spi_flash, esp_partition_read, \
n0 = esp_partition_read((const esp_partition_t *) a3, n2, a1, n0); NIPn(3)) \
YV(spi_flash, esp_partition_write, \
n0 = esp_partition_write((const esp_partition_t *) a3, n2, a1, n0); NIPn(3)) \
YV(spi_flash, esp_partition_erase_range, \
n0 = esp_partition_erase_range((const esp_partition_t *) a2, n1, n0); NIPn(2)) \
YV(spi_flash, esp_partition_mmap, \
n0 = esp_partition_mmap((const esp_partition_t *) a5, n4, n3, \
(spi_flash_mmap_memory_t) n2, \
(const void **) a1, \
(spi_flash_mmap_handle_t *) a0); NIPn(5)) \
YV(spi_flash, esp_partition_get_sha256, \
n0 = esp_partition_get_sha256((const esp_partition_t *) a1, b0); NIP) \
YV(spi_flash, esp_partition_check_identity, \
n0 = esp_partition_check_identity((const esp_partition_t *) a1, \
(const esp_partition_t *) a0); NIP)
#include "gen/esp32_spi-flash.h"

55
esp32/optionals.fs Normal file
View File

@ -0,0 +1,55 @@
\ Copyright 2023 Bradley D. Nelson
\
\ Licensed under the Apache License, Version 2.0 (the "License");
\ you may not use this file except in compliance with the License.
\ You may obtain a copy of the License at
\
\ http://www.apache.org/licenses/LICENSE-2.0
\
\ Unless required by applicable law or agreed to in writing, software
\ distributed under the License is distributed on an "AS IS" BASIS,
\ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
\ See the License for the specific language governing permissions and
\ limitations under the License.
internals DEFINED? assembler-source [IF]
assembler-source evaluate
[THEN] forth
internals DEFINED? xtensa-assembler-source [IF]
xtensa-assembler-source evaluate
[THEN] forth
internals DEFINED? riscv-assembler-source [IF]
riscv-assembler-source evaluate
[THEN] forth
internals DEFINED? camera-source [IF]
camera-source evaluate
[THEN] forth
internals DEFINED? interrupts-source [IF]
interrupts-source evaluate
[THEN] forth
internals DEFINED? oled-source [IF]
oled-source evaluate
[THEN] forth
DEFINED? rmt-builtins [IF]
vocabulary rmt rmt definitions
transfer rmt-builtins
forth definitions
[THEN]
internals DEFINED? serial-bluetooth-source [IF]
serial-bluetooth-source evaluate
[THEN] forth
internals DEFINED? spi-flash-source [IF]
spi-flash-source evaluate
[THEN] forth
internals DEFINED? HTTPClient-builtins [IF]
vocabulary HTTPClient HTTPClient definitions
transfer HTTPClient-builtins
forth definitions
[THEN] forth

Some files were not shown because too many files have changed in this diff Show More