/r/Forth
"In particular you need to avoid writing code for situations that will never arise in practice. You need to avoid writing code to handle a general problem that you are never going to encounter. I don't need to solve the general problem when I only have to solve these specific cases." -- Chuck Moore
You can try things out interactively as you build your system. The compiling functionality is an exposed part of the language like everything else.
It can be used to debug itself!
Forth has no baked-in syntax or privileged data structures -- programming is done by extending the language to your application. Thus, it can become what ever you need it to be and fit the problem like a glove.
Forth has a "low floor; high ceiling" approach to abstraction -- that is, it can be both low level, high level and anywhere in-between.
You can do more with less. Forth fits in very small storage spaces.
Forth is one of the few environments which is totally comprehensible by one person.
Starting Forth - A fun, illustrated introduction.
A Beginner's Guide to Forth - A faster-paced, somewhat less whimsical guide.
Jonesforth - How to write a Forth.
Thinking Forth - A Language and Philosophy for Solving Problems
Forthwrite Magazine - From FIG UK.
Forth Dimensions - magazine archive.
The Journal of Forth Application and Research
comp.lang.forth - Forth newsgroup.
ForthHub community on GitHub
/r/concatenative - Anything related to the use, theory, or implementation of concatenative programming languages.
/r/programbattles - Battle it out between likeminded coders to create the best code possible!
/r/Forth
Hello.
I'm on an older Forth (JForth on Amiga). But it should conform to a mixture of '79 and '83 and FIG.
I'm wondering how is it possible to print (or find out without printing) the name of the word that is currently executing?
https://eforthwin.arduino-forth.com/article/examples_serial_serialTRandRC
During the Forth developments using the serial link, some small problems appeared that had to be fixed. Rather than correcting and completing the previous chapter, I preferred to explain here the evolutions of the code managing the serial port.
Like many Forth users, I am a veteran of 1980s home computing. I had an upgraded Dragon 32 with 128K RAM, 2 disk drives, OS-9, a Forth "Development Environment" (if you can call it that!) and an 80 column display. This was a fairly popular upgrade in the late 80s. I enjoyed Forth, but I stopped using it after I went to university and the focus changed to Pascal.
I have a relatively complex life as befits a person in their 50s trying to hold together various responsibilities, including managing accounts for various entities. I use ledger-cli which requires various inputs (APIs etc) that I wish to automate. It's a collection of command-line tools, bash scripts, perl scripts etc. At present I run these manually and add the output to my ledger-cli ledgers.
I have been looking into various DAG-based orchestration tools such as Airflow but it seems insane to orchestrate my scripts using something so enormous.
I have been playing around with gforth simply for nostalgia's sake when it hit me: perhaps I could use it to orchestrate my ledger scripts. I could build up a dictionary of words that allow me to define and run a DAG using Forth.
Is this something anyone here has had a go at? Or am I barking up some completely crazily wrong tree here?
I've released the first version (well, the second...) of my "zemanim" calculator app, for all the platforms 8th currently supports (iOS missing still, coming soon).
Includes the source code for those who are curious what a full-blown app in 8th might look like.
Our final release for 2024!
Tons of fixes and improvements, ]details on the forum](https://8th-dev.com/forum/index.php?topic=2926.0).
Also began our year-end sale, through New-Years Day.
Hi all,
I've been working on a custom Forth interpreter in Swift for a while now. It can't do much beyond fibonacci yet but the codebase should be relatively approachable.
Before I continue, I want to give a shout out to r/spelc for his awesome VFX Forth. It's been truly an inspiration to me, but I want to assure him that I am not using it to leach concepts from. My Forth is my own work. I'm not using or even looking at any of the VFX forth sources that come with the product. It's unfortunate for me because there's many man years' of innovation that I'm going to maybe have to implement on my own. I also want to assure him that I respect his intellectual property utmost.
It's gotten to the point where bochs' debugger is not so useful since it doesn't know how to find symbols in the dictionary - it's all just a bunch of hex addresses.
So I'm implementing my own debugger.
I intend to use the TRACE bit, debug registers, software breakpoints, and INT3/INT1 instructions. I'm trying to write as much of the debugger in Forth as possible, but it's a strange environment. The breakpoint instruction causes an exception, and the exception handler saves the state of the current task (my Forth has true multitasking, see the output of the PS word in the screenshot) and sets up a fake Forth environment so words can "sort of" be defined and execute. For example, I have a dedicated data and return stack for the debugger - it's not using the current Task's environment because the whole idea is to be able to examine that environment without cruft added by the debugger.
While debugging, stepping, running until breakpoints, etc., the context will be switching between debugger context and freely running multitasking system/Forth. Implementation of "step out" is going to be something like:
set trace bit
return to Forth
trace handler checks for RET instruction and does a single step if found
otherwise go back to step 1
Something the debugger has to do is to save the byte of the instruction at a breakpoint and replace it with an int3 instruction. When the breakpoint is hit, the bytes saved need to be restored. When execution is continued, those breakpoint bytes need to be restored. So call it "enter" and "leave" the debugger. I may end up having the debugger save and restore more than breakpoints - perhaps intercepting certain DEFERed words like QUIT and ABORT so calling those return properly to the debugger instead of to the Forth inner loop.
This scheme for my debugger is somewhat problematic because not all the base Forth words I've defined work as expected. For example, .S (print stack) will print the task's stack, not the debugger's and the debugger's stack is important to be able to view. The debugger commands currently have the form: ```<COUNT> command``` as in ```10 step``` or ```10 disassemble```. But using the regular dictionary is important for inspecting things - ```SEE someword```.
It's also problematic because I'm ending up writing my own Debugger.Quit, Debugger.Accept, Debugger.Interpret, and so on. I'm thinking that I may use a FLAGS bit in the dictionary structure to indicate words that can be called from debugger context. Some words like + and - and * and NOT obviously need to be callable.
It's also possible to fully implement the debugger in assembly language, but I would be incrementally adding functionality where existing Forth words already provide that functionality.
Here's what it looks like so far:
This concept made my brain hurt. I made a feature branch to implement it a few times before tossing them.
The more I work on my Forth implementation, the more building block words I have to implement new concepts.
My Forth is STC for X86/64. A long time ago, I made the dictionary header have a CFA field that my assembly macros and CREATE words automatically fill in to point at the STC code. INTERPRET finds a word and calls >CFA to decide to call it, compile it inline, or compile a call to it.
For DOES>, I compile in a call to (DOES) and a RET. The RET ends the CREATE portion of the defining word. After the RET is the DOES part of the word (runtime). (DOES) compiles a call to the LATEST's >CFA and then stores the address of the RUNTIME in the CFA field. So code that call the defined word does something like "call word, word calls old CFA to do the DOVAR or whatever, and then jumps to the RUNTIME.
It's not super hard, but it took a lot of trial and error and debugging to see the state of things at define, create, and run times.
To clarify things a bit, here's the defining word X and using it to define Z and executing Z. It works as expected. For clarity, x is defined as : x create , does> @ ;
I haven't tested it beyond what you see, but I think multiple DOES> is going to work find, too. Due to the handy chaining of words property of the dictionary, each DOES> will call the old CFA which is the previous DOES> and it should work. I'll test it at some point (I'm having too much fun expanding the functionality vs. writing tests.
Here's the source to DOES> and (DOES). Being an STC Forth, many of my words are designed to generate machine code versus generating call, call, call type threads.
Structure management has just undergone a major facelift in version 7.0.7.21 of eForth. Discover the new feature that makes managing fields in a structure much simpler.
https://eforthwin.arduino-forth.com/article/elements_evolStructures
zeptoforth 1.9.1 has been released. This release renames the int-io
module to serial
(the old, now-deprecated int-io
name is retained for the time being but will be removed in a future release), fixes a major timing issue with the CYW43439 driver on the Raspberry Pi Pico 2 W, and fixes a number of numeric literal parsing issues. You can get it from https://github.com/tabemann/zeptoforth/releases/tag/v1.9.1.
Note that there are issues with the USB CDC driver on the RP2350 which make it difficult to reliably upload the CYW43439 firmware, the CYW43439 driver, and zeptoIP to the Raspberry Pi Pico 2 W with it. Consequently it is highly recommended one use the serial console for this purpose. If one is using a full_usb
build one can temporarily switch to the serial console with serial::serial-console
.
Hello!
So, I've built a My4TH board, it's got a 16 bit Forth 2012 implementation on it, and it's pretty sweet. Because it has an onboard i2c interface, I've been trying to talk to an AHT10 temperature sensor, and I've got it going! But now I'm unsure how to do the math. So I run the word:
Terminal ready
ok
aht10 ok
hex ok
. 11 ok
. C8 ok
. 5 ok
. ? stack
So I'm getting 5C811 out of the sensor. The formula to get the result in degrees Celcius would be: (value / 2^20) * 200 - 50, and if we run the math, I'm getting (378897/1048576) * 200 - 50 = 22.26! So I'm getting valid data, and the math works, but I'm a bit unsure how I'd go about that. So assuming you've got those values on the stack, how to calculate?
Thanks in advance, this is my first foray into Forth on a small machine, and it's pretty cool!
Released the sources of my Forth dialect / compiler for 32-bit ARM (armv6) : https://github.com/grz0zrg/GnosTh
Also did some write-ups, one of which might be of interest for people's that want to use something like U-Boot API to ease I/O at low level on some boards.
Das U-Boot API at ARM level : https://www.onirom.fr/wiki/blog/30-11-2024_writing_a_small_forth_based_rpi_os_part_1_easy_io_with_uboot_for_baremetal_usage/
Forth dialect ARM implementation : https://www.onirom.fr/wiki/blog/30-11-2024_writing_a_small_forth_based_rpi_os_part_2_arm_forth_dialect_implementation/
Accessing structure data is tricky. This article aims to provide as simple and clear instructions as possible to help you deal with structures.
https://eforthwin.arduino-forth.com/article/elements_plusStructures
We will now see how to manage fonts. This is an essential step to manage a rich display in graphic mode. Font management is very complex. We will only cover the essential parts here.
https://eforthwin.arduino-forth.com/article/graphic_fontesCaracteres
0 value hFontArial16 \ handle for selected font
: selectFontArial ( -- )
16 \ Hauteur de la police en pixels
0 \ Largeur moyenne des caractères
0 \ Angle d'échappement
0 \ Orientation
FW_NORMAL \ Poids de la police (gras, normal)
FALSE \ Style italique
FALSE \ Souligné
FALSE \ Barré
DEFAULT_CHARSET \ Jeu de caractères
OUT_DEFAULT_PRECIS
CLIP_DEFAULT_PRECIS
DEFAULT_QUALITY
DEFAULT_PITCH FF_SWISS or
z" Arial" \ Nom de la police
CreateFontA to hFontArial16
;
Discover the first plots with eForth Windows. This chapter is an opportunity to better discover the principles of programming using the Windows graphics API.
https://eforthwin.arduino-forth.com/article/graphic_premierTrace
The first thing we want to do, apart from graphical drawings, is to be able to display text in a Windows window. So, let's take a deep breath, then tackle this very vast subject, but also very rich in possibilities!
https://eforthwin.arduino-forth.com/article/graphic_ecrireTexte
: STR01 ( -- addr len )
s" This is my first example.. I try to draw a very long text in this graphic window." ;
: FORMATTING ( -- n )
DT_TOP \ draw frop top
DT_WORDBREAK OR \ break words
DT_CENTER OR \ center text
;
: DRAWtext ( -- )
10 10 200 120 LPRECT RECT!
$ff0000 to color
hdc STR01 LPRECT FORMATTING DrawTextA
;
Modal boxes are an integral part of the Windows environment. They are very useful for displaying information or issuing a warning. When closing the modal box, you can even recover certain choices caused by closing the modal box.
https://eforthwin.arduino-forth.com/article/api_afficherBoiteModale
z" Will you continue?" constant lpText
z" make a choice" constant lpCaption
: MSGbox ( -- )
NULL lpText lpCaption MB_YESNO MessageBoxA
?dup if
cr ." You have pressed: "
case
6 of ." Yes" endof
7 of ." No" endof
endcase
then
;
This release:
of
/ofstr
... endof
to collect all end branches to the end of case
... endcase
/endcasestr
blocks (except on the RP2040 and STM32L476, due to the limitations of these platforms)You can get it from https://github.com/tabemann/zeptoforth/releases/tag/v1.9.0.
I did a thing that you may find interesting
Download our app and start programming on your phone right now. RIGHT NOW!
apps.apple.com/gb/app/hencefo…
Here, ANSI Sequences for emulated VT terminals:
https://github.com/MPETREMANN11/Z79Forth/blob/master/VT525/vt525.4th
The content of this file has been tested with the Tera Term terminal in VT 525 emulation. Its content allows:
* position the display
* color the text and the background
* memorize and restore the cursor position
* a real screen erase
And above, a photo in 3D (anaglyphe) from the Z79Forth card:
This release adds string constants not limited to 255 characters, optimizes of
... endof
blocks (except on the RP2040 and STM32L476), allows direct control over task deadlines with the deadline scheduler, optimizes zeptoIP using the deadline scheduler, and fixes a bug where if a task were blocked long enough its deadline would "wrap around" resulting in it being incorrectly scheduled. You can get it from https://github.com/tabemann/zeptoforth/releases/tag/v1.9.0-beta.3.
https://eforthwin.arduino-forth.com/article/flog_premiersFaits
An expert system evaluates rules based on facts. We will study in detail how to define facts. To do this, we will enter into the mechanics of how the FORTH language works to describe facts, whether predefined or not.
In this first chapter devoted to an elementary expert system, we will approach the beginnings of the construction of such a system. Each new chapter will unfold the design of such a system in detail.
In this article, we will explore a few cases of data structures. The goal is to give ideas for your own structures, starting with one- and two-dimensional arrays. This article ends with the use of the structures vocabulary.
https://eforthwin.arduino-forth.com/article/elements_dataStructures
I am looking for a [flashforth driver for the 20 x 4 character display LCD2040 with I²C interface. I²C address $25. Any suggestions?