Updates to BASIC EXEC
Posted: Wed Oct 09, 2024 6:46 am
Is it possible/practical to have EXEC updated/extended to support true self-modifying BASIC code?
Tony and I have kicked this idea around. I'm thinking more in terms of the running BASIC code itself is generating the new plain-text line of code (with line numbers), and somehow using EXEC to get the new line (or modified existing line) tokenized "on the fly."
As a couple use cases:
imagine I have a DEF FN, but I want to dynamically alter what the FN does (like maybe change SIN to COS, but doing so based on some other state change and not have to do an IF check). What if the running program itself could generate a whole new line of code, and get that line updated - as an interpreted language, it seems this should be possible (but yes, require some extreme mastery of the existing ROM BASIC)
I think the real constraint is that the V2 BASIC needs to have bi-directional pointers for the tokenized line. The old 1975 IBM 5100, its ROM BASIC worked like that, each line of BASIC was prefixed with "next"/"prev" pointers, so they didn't necessarily have to be linear or co-located. So if you typed like 10, 20, 30, then added a line 15 - it wasn't stored in memory in the line number order, but in the order the user typed it (and the next-pointer associated with line 10 would jump to whatever line 15 was). I think they used the PREV pointer so you could press up arrow and at the top of the screen, it could find the prior line and display it (so you could scroll your code both up and down off the edges of the screen).
As another example, suppose I draw a random box, or decide the size of a box based on other criteria. Traditionally you'd have code like IF X < LEFT.SIDE.OF.BOX THEN TRIGGER.SOMETHING... But with self-modifying code, you could update this line in-place (so you didn't need a variable corresponding to LEFT.SIDE.OF.BOX - the line would be hard-coded to whatever the current numeric value was). I'm not sure if there is really any meaningful performance improvement (in terms of making a game or some content that wouldn't otherwise be possible without this feature) - but it's just a general gist of what this capability could be used for.
Anyhow, Tony and I kicked around some ideas - right now, the BASIC program could load its own plain-text form entirely (with the modified line), then EXEC that, then END itself - but then be bloated with checks to help resume where it had left off. I'm not sure if the idea of "self modifying BASIC" would have other more interesting uses - but I'm not aware of any 8-bit or boot to BASIC system that did have a feature like this.
Without a PREV flag in the format of tokenized lines, maybe it's just not practically possible to do. But just tossing the idea out there for consideration. I suppose another negative is, I'm not sure if BASLOAD could handle this feature. I suppose if in the self-generated lines, if you set them to be high line numbers (like 20000), you could produce some whole routines "on the fly." But modifying existing lines might not be practical.
Tony and I have kicked this idea around. I'm thinking more in terms of the running BASIC code itself is generating the new plain-text line of code (with line numbers), and somehow using EXEC to get the new line (or modified existing line) tokenized "on the fly."
As a couple use cases:
imagine I have a DEF FN, but I want to dynamically alter what the FN does (like maybe change SIN to COS, but doing so based on some other state change and not have to do an IF check). What if the running program itself could generate a whole new line of code, and get that line updated - as an interpreted language, it seems this should be possible (but yes, require some extreme mastery of the existing ROM BASIC)
I think the real constraint is that the V2 BASIC needs to have bi-directional pointers for the tokenized line. The old 1975 IBM 5100, its ROM BASIC worked like that, each line of BASIC was prefixed with "next"/"prev" pointers, so they didn't necessarily have to be linear or co-located. So if you typed like 10, 20, 30, then added a line 15 - it wasn't stored in memory in the line number order, but in the order the user typed it (and the next-pointer associated with line 10 would jump to whatever line 15 was). I think they used the PREV pointer so you could press up arrow and at the top of the screen, it could find the prior line and display it (so you could scroll your code both up and down off the edges of the screen).
As another example, suppose I draw a random box, or decide the size of a box based on other criteria. Traditionally you'd have code like IF X < LEFT.SIDE.OF.BOX THEN TRIGGER.SOMETHING... But with self-modifying code, you could update this line in-place (so you didn't need a variable corresponding to LEFT.SIDE.OF.BOX - the line would be hard-coded to whatever the current numeric value was). I'm not sure if there is really any meaningful performance improvement (in terms of making a game or some content that wouldn't otherwise be possible without this feature) - but it's just a general gist of what this capability could be used for.
Anyhow, Tony and I kicked around some ideas - right now, the BASIC program could load its own plain-text form entirely (with the modified line), then EXEC that, then END itself - but then be bloated with checks to help resume where it had left off. I'm not sure if the idea of "self modifying BASIC" would have other more interesting uses - but I'm not aware of any 8-bit or boot to BASIC system that did have a feature like this.
Without a PREV flag in the format of tokenized lines, maybe it's just not practically possible to do. But just tossing the idea out there for consideration. I suppose another negative is, I'm not sure if BASLOAD could handle this feature. I suppose if in the self-generated lines, if you set them to be high line numbers (like 20000), you could produce some whole routines "on the fly." But modifying existing lines might not be practical.