I love wasting time!

5 views
Skip to first unread message

The Beez

unread,
Sep 18, 2026, 10:06:04 AM (4 days ago) Sep 18
to 4tH-compiler
Hi 4tH-ers!

We have LATEST for a while now -- but I was always looking at <BUILDS, because with it you could make wonderful constructs like:

s" seven" 16 string seven   <builds place does> count type cr ;
31416 -4     float array pi <builds 2! does> 2@ ;

Now -- is that syntactic sugar or not? But LATEST is not a normal word. It's encoded in GetSymbol() as:

  if ((x == Object->Symbols) && (Object->Symbols > 0))
    if ((len == 6) && (! MatchName ("LATEST",  Symbol)))
       x = Object->Symbols - 1;

It translates to "If you didn't find the requested Symbol, and a Symbol has been defined and the name of the Symbol is LATEST and its length is six, then the Symbol is the Symbol last defined".

So I thought, what if I make it an Immediate word? So I did:

#ifndef ARCHAIC
  static void DoBuilds (void)
#else
  static void DoBuilds ()
#endif

{
  int x = Object->Symbols - 1;

  if (x < 0) Object->ErrNo = M4NONAME;
  else CompileWord (Object->SymTable [x].Token, Object->SymTable [x].Value);
}

And at first it seemed to work just fine. Until I tried some of the more exotic constructs:

0 value six 6 to latest latest .
: Hello ." Hello" cr ; ' latest .

Then it failed. "Well," I thought "May be I didn't use it as often." So I checked. Normal 4tH programs? Nothing. Library 4tH programs? Nothing. So I set out to document the whole shebang.

And then I had an idea. What about the preprocessor programs? And that was a very, very good idea. Because it was heavily used in FOOS, e.g. for defining default methods. Several OOP programs would have stopped working instantly.

So .. I rolled back the entire thing. Fortunately, I'd kept the old source, so it was pretty easy. Documentation -- not too bad either.

So after all that hacking -- I was right back where I started! Note -- that's not the first time. That's how a program grows -- by simply trying things.

And while doing the work, I had an idea. I needed just one single line to accommodate that functionality:

  if ((x == Object->Symbols) && (Object->Symbols > 0))
    if (((len == 6) && (! MatchName ("LATEST",  Symbol))) ||
        ((len == 7) && (! MatchName ("<BUILDS", Symbol))))
       x = Object->Symbols - 1;

But after all that, I just didn't feel it anymore. Maybe I'll do a preprocessor thing, like:

:macro <builds latest ;

It's easy. It's simple. Just three words.
But: what do you think? Is it worth it -- or just a waste of time (again!). Let me know!

Hans Bezemer


Reply all
Reply to author
Forward
0 new messages