Cleaning up the uBasic syntax

43 views
Skip to first unread message

The Beez

unread,
Nov 18, 2023, 10:08:49 AM11/18/23
to 4tH-compiler
Ok 4tH-ers!

I know not everybody is in uBasic/4tH, but bear with me. Forth has the reputation of being a "read only" language - which I always counter with the argument "Badly written code is read only" - it has nothing to do with the language.

I've been doing this 75 KLOC project for 30 years - and I still modify code decades old. uBasic/4tH grew from a 15K program to a whopping 50K program - and I still change it.

Now, this week I was playing with some SVG related code - and thought "That DUP() function really annoys me. How can I fix that?"

It didn't take me long to find the culprit. I took me even less time to fix it - by just modifying ONE SINGLE WORD.

Now, the "problem" was in the GET_PUSH word, which read:

get_exp dstack adepth #user < if dstack >a ;then E.STFULL throw

But there is a word which takes care of the "quoted string", while remaining fully compatible with GET_EXP. As a matter of fact, DUP() is defined as:

aka string> (dup)

And now you know the solution:

string> dstack adepth #user < if dstack >a ;then E.STFULL throw

And that's it. Now the code reads a much cleaner:

Proc _SetMode ("pixel")
Proc _SetColor (FUNC(_Color ("Blue")))
Proc _SetFill (FUNC(_Color ("Yellow")))
Proc _SVGopen ("test.svg")
Proc _Canvas (200, 200)
Proc _Background (FUNC(_Color ("White")))
Proc _SetPixel (0,0)
Proc _SetPixel (100,0)
Proc _SetPixel (0,200)
Proc _SetColor (FUNC(_Color ("Red")))
Proc _Line (100, 0, 0, 200)
Proc _Circle (120, 100, 50)
Proc _SetColor (FUNC(_Color ("Blue")))
Proc _SetFill (FUNC(_Color ("Green")))
Proc _Ellipse (100, 100, 20, 40)
Proc _SetColor (FUNC(_Color ("Red")))
Proc _TextSet ("Vertical")
Proc _Banner (20, 30, "Test image")
Proc _SVGclose
End

I seriously doubt the necessity of a function like DUP() - but I'll leave it in for the time being for three reasons:
  1. I'm not completely sure it hasn't a function somewhere. I don't say it isn't fixable, I just say I might encounter it - and then decide to either drop it or leave it as is;
  2. It's not only the programs I provide with 4tH, it's also all the code on the web. So far I've only built upon the core - with the exception of the (now defunct) CHOOSE keyword;
  3. It doesn't occupy much code in uBasic/4tH. As a matter of fact: none. It's just a few table references, that's all.
Of course, there is a slight performance penalty involved. But mostly for compatibility reasons, there are plenty of such constructions. E.g. NEXT really doesn't need a variable, but for compatibility reasons, it's supported. THEN allows for a naked label - without a GOTO.

Also, when you consider the entire statement, there is plenty going on there. This change is only a minor portion of the entire code executed.

Ok, I hope you liked it. If I got something to show in regard to the SVG support, you'll know. BTW, it's based on the SVG module of 4tH, so you'll have little trouble learning and using it.

Hans Bezemer





The Beez

unread,
Nov 19, 2023, 11:15:32 AM11/19/23
to 4tH-compiler
Well, two things:

  1. First, I've made the change in uBasic/4tH permanent. There is nothing like testing a new feature as by simply using it. It's not the first time I took that approach and so far I've been lucky;
  2. I thought, let's dive in. So I've made a dragon curve in uBasic, without any Turtle graphics. And it seems to work just fine: https://sourceforge.net/p/forth-4th/code/HEAD/tree/trunk/4th.src/apps/basic/dragoncv.bas
Code in SVN.

Hans Bezemer

The Beez

unread,
Nov 27, 2023, 4:24:26 AM11/27/23
to 4tH-compiler
Some updates in that regard:
  • I don't like being "locked in", so I removed all superfluous DUP()'s from both published code on the web as well from the repository. So now that problem is non-existent;
  • I've given some thought on the issue. You always have to consider that simply removing DUP() as a function may hit some existing user code. That's not nice. People could get angry. And they would be right. That's not how a developer of a language should behave;
  • I personally think that it's much more agreeable to declare it obsolete - and give people an acceptable time to adjust, rather than to force them to adjust right away. So in the coming releases of uBasic/4tH, DUP() will still be supported.
While converting the sources I found no occasion where DUP() was still required. For assignment you can use := and for all PUSH related issues (including passing parameters from and to subroutines), well - those are completely resolved. So I honestly think we have a case here.

Hans Bezemer

Reply all
Reply to author
Forward
0 new messages