Today marks the 133rd anniversary of the admission of Wyoming to the United States. Yes, we have so few holidays of interest for today, that I had to resort to another state anniversary.

The state flag of Wyoming, in the shape of Wyoming

Yeah, I don’t have anything else. On to the project discussions, I guess.

Social Media

Auto-posting to the blog’s Matrix room works smoothly. If anybody joins besides me—hint, hint—you’ll at least know exactly when blog posts go out, even I haven’t personally posted lately.

I do show up regularly, though, usually in the mornings and evenings, a lot like my Mastodon and Cohost schedule. If anybody other than me wants to have such a thing, I use the nheko client, which seems to dress up the experience and feels a lot snappier than the (also quite nice) Element web interface.

Oh, and it also looks like my selected Lemmy instance has vanished from the Internet. Presumably, that means that you should not look for me there, until either the server comes back, or I give up on that prospect. It feels unfortunate; even though I didn’t post much, I did see some interesting discussions. 🤷

Even though this post includes code on Codeberg, I admittedly don’t know if I appreciate the first impression that it made on me. No sooner had I published a repository, but someone filed a nonsensical ticket against it. I deleted the ticket without comment, but the system doesn’t (yet) provide the ability to block bad actors. That sort of attitude makes me nervous, since it means that a sufficiently motivated creep could waste the time of any project that they don’t care for, with no way to slow them down.

Mastodon Tool Trunk

GitHub - jcolag/tool-trunkTools for (John's) Mastodon workflow. Contribute to jcolag/tool-trunk development by creating an account on GitHub.

Other than generally cleaning things up, the Rummager now gets a list of every toot ID that it sees—reblogged or original—and stores it to a Pantry basket. Since I already have the filtering in place, this means that the page will never show the same toot twice.

It doesn’t yet work, unfortunately, but the process has begun for figuring out how to make HTMX work for, at least initially, the management buttons—like, share, and so forth—on each toot. The documentation makes this look like little more than giving the button an API endpoint to hit, and since I know that for each button, I tentatively have high hopes.

John’s BASIC Interpreter

Codeberg — basic-interpreterjcolag/basic-interpreter An old start to a 1970s-style BASIC interpreter with configurable language features.

I happened to find what I think will make a good test case to see if Codeberg can work for me—procedurally, not functionally, since it definitely serves the functional role of “exists to host git repositories”—as well as GitHub does, though it might not make sense to people who don’t actually know me. As such, let me provide some background.

You might want to buckle in for a story long enough to warrant its own post, that I need to make the actual update, here, sound comprehensible.

As long-time readers may already know, for more than fifteen years, I taught graduate computer science classes at the college that I graduated from. Among the handful of courses that I taught for the longest run, I had a class in programming languages, which I treated somewhat experimentally. I used the lectures to cover the “theory”—quoted because the school didn’t want type theory in the curriculum, and if you don’t have type theory, your theory reduces down to something like stamp collecting—homework gave the students experiences with the features discussed in class, and exams had them analyze and choose features in context. Most students seemed to like it—the department kept me teaching it—and even the few who complained, by their own admission, mostly did so on the basis that they wanted to memorize and repeat things.

Tangent-from-the-Tangent: If I had to do this over again, I would probably swap the lectures with the homework. I believe that the education experts currently call that an “inverted classroom,” where you take advantage of the lack of interactivity in lectures by sending them home with the students as video or text. Then, you put the practical work in class, where students can fail together and actually need to ask questions, instead of only asking questions because the instructor looks lonely at the front of the classroom…

Anyway, in my first couple of runs through the course, I gave the students different languages to highlight each feature that we covered, expecting them to learn the absolute minimum required by the question—documented by me as a page stored on a school-hosted website—and move on to the next problem. Instead, many tried learning each language from community documentation, not knowing where to stop, and ended up spending multiple hours on each question that I expected to take them twenty minutes in total including research.

I can’t fault their ambition.

To fix that problem in future years, I decided to designate an official class language to handle the heavy lifting, and make it configurable to add and remove language features as the students needed them. This would allow me to cover the vast majority of constructs that we’d talk about in class—conditions, loops, subroutines, and so forth—while drastically reducing the number of languages that the students would need to learn.

For the base language, I chose an old-style BASIC, for a handful of reasons.

  • I grew up programming in 8-bit BASICs, so I knew the central concepts well enough to design the interpreter’s architecture.
  • Since they used to teach BASIC in elementary schools, I didn’t see any concerns about adults learning the core language.
  • Because old BASICs run line-by-line, the interpreter can effectively treat each line of a program like a separate program, thereby making that architecture less complicated, and putting less of a burden on students learning it for the first time.
  • In addition, BASIC commands rarely have much to their grammar, often looking more like command-like operations with a command followed by one or more parameters.
  • Few enough people programmed significantly in older styles of BASIC that it put most of the class on even footing, instead of needing to worry that a hypothetical LISP or PERL assignment would favor students who happened to use them every day.
  • Line numbers make no sense when you try to explain them at a whiteboard, but I’ve never seen anyone not understand the concept after needing to use them for a couple of minutes.
  • Honestly, it also felt nice to share that experience with students, including accepting their bug reports.

For more complicated language ideas, like data structures, I would still bring in other “toy” languages for them to work with, carefully explaining what they needed to know in the assignment text and providing them with a “starter” program, instead of hoping that they would read supplemental material.

In any case, I never released the code for the BASIC interpreter, except maybe to one student who had an odd machine/processor that they used at home, where they needed a custom build that I couldn’t supply; Microsoft tried to target DEC’s ALPHA processors at around this time, I believe. But I found a copy of the code last week, and brushed off the dust, so that other people can play with it.

For reference, I never finished what both I and my students considered important language features.

  • The interpreter only supports one data type, the floating point number. It almost certainly could support them, but we never needed the feature for an assignment, so much as people wanted it for completeness.
  • It also doesn’t support functions, neither built-in nor user-defined. This seems more difficult than adding strings and integers, but probably still doable.
  • You may only have one statement per line, rather than including the ability to separate statements with colons. It would complicate the parsing to fix this, though probably not too much.
  • Variable names can run for far longer than the traditional two-character maximum. I imagine that this wouldn’t take much effort to fix, though you’d want this enforced at the parser level, because of how it uses some variable names internally when using certain “advanced” features.
  • It could use better tooling than LOAD, SAVE, LIST, and RUN. I don’t remember if it even has a command to exit the interpreter.

I don’t know if I’ll make many updates to this, myself. After all, I wrote most of this code almost twenty-five years ago, haven’t given it any thought in almost a decade, and—as you might guess—have no immediate need for a BASIC interpreter. But someone (me or someone else whose work I’d happily review) could make those updates, and make this a sufficiently credible interpreter to jump on the retro-computing bandwagon.

The code itself? It looks like it comes to about two thousand lines of C, with a hand-coded recursive-descent parser and some dynamic data tables. The formatting that I used back then boggled the mind.

int lookup (char * name)
{
 int     i,
         l;
 char   *c,
        *s,
        *t;

 l = strlen (name) + 1;
 t = s = (char *) malloc (l);
 memset (s, 0, l);
 for (c=name;*c;c++)
        *t++ = (char) tolower (*c);
 for (i=0;i<MAXSYM;i++)
        if (!strcmp (s, symtab[i].name))
                return (i);
 return (-1);
}

Yikes, right? That completely mystifies me. I have no idea where this “style” came from, assuming that I didn’t decide on it to deliberately look different. The variables especially induce a headache. Don’t even get me started on the spacing choices or the lack of blocks to ensure clarity. But I deliberately reformatted the code after the initial commit, so you can still look at the original in its horrid glory, if you prefer.

And don’t worry about keeping track of all this information, if you find it interesting. Depending on whether I got distracted in publishing this post, I either added this—along with the documentation for command-line options—to the repository’s README.md file moments ago or will do so as soon as the blog post announcements go out on social media. I know that it’ll definitely happen at around the same time, though, because I want to run this through the grammar checker and similar tools, before posting it anywhere.

Entropy Arbitrage

GitHub - jcolag/entropy-arbitrage-codeThe Jekyll blog for https://john.colagioia.net/blog - jcolag/entropy-arbitrage-code

You already saw the ugly first draft version of this, in the previous section about my BASIC interpreter. For clarity, though, I spent some time and added a plugin to the blog for linking to repositories on Codeberg.

The good news? It works, and the code doesn’t look too different from my original GitHub plugin, even sharing the same cache file.

The bad news? The final result looks pretty close to hideous, because Codeberg doesn’t provide a nifty little all-in-one project banner image for repositories, like GitHub does. Their Open Graph metadata also doesn’t provide enough information to build a comparable image. And Font Awesome doesn’t even have an iceberg glyph, which feels like adding insult to injury…

Anyway, I’ll think about how to make this look less egregious, going forward. Or maybe I’ll take the lack of Open Graph metadata as a sign that I shouldn’t use Codeberg…

Library Updates

I needed to bump library versions for Picture to Nonogram.

Next

For this week, I want to figure out the HTMX calls in the Trunk Rummager, and make the Codeberg plugin look less like a complete eyesore; maybe I can fix the latter before anybody notices. I may also continue to tinker with the BASIC interpreter.


Credits: The header image is Wyoming by Andrew Rohletter, contributed to the public domain by the creator.