Modernizing BASIC: Implementing Method Chaining in jdBasic
Introduction
Who said BASIC has to be clunky? I’ve been working on the object-oriented features of jdBasic, and I realized something was missing. I wanted the code to flow more naturally, specifically when initializing or manipulating objects.
Today, I successfully implemented Method Chaining (often called a Fluent Interface) into the interpreter.
The Goal
In standard BASIC (and many older languages), performing multiple operations on an object usually looks like this:
DIM calc AS T_CALC calc.init(10) calc.add(5) calc.multiply(2) calc.print_me()
It works, but it's verbose. I wanted to be able to write it like a sentence:
calc.init(10).add(5).multiply(2).print_me()
The Implementation
Getting this to work required a deep dive into the C++ runtime environment (`NeReLaBasic.cpp`). The challenge wasn't just syntactic sugar; it was about how the interpreter handles state between statements.
There were two main hurdles:
- `RETURN THIS`: I had to implement a mechanism for a function to return its own object context. In `Commands.cpp`, I updated the variable lookup to intercept the keyword
THISand inject the current object instance from the stack back into the local scope. - Dot-Chaining Statements: The interpreter naturally sees
calc.init()as one statement. When it reached the next dot.add(), it originally saw a syntax error. I had to modify the main statement loop to recognize a leading dot as a continuation of the previous statement's return value (`RETVAL`).
The Result
The result is a syntax that feels strangely modern for a BASIC dialect. It allows for concise, readable code that "flows" down the screen.
' This is now valid jdBasic code! calc.init(1) _ .add(2) _ .mul(3) _ .print_me()
It feels so wrong, but so right.
Check out the source code on GitHub to see the changes in `NeReLaBasic.cpp` and `Commands.cpp`!