Neolithic Tiny Basic
Re: Neolithic Tiny Basic
Rats... I came up with a mechanism to include if/else/endif rather than just if/endif, which worked nicely... until I realised that if there were no 'else' clause, it had to scan the whole of the basic program text before it didn't find it (if you see what I mean).
A rethink is required, methinks!
Neil
A rethink is required, methinks!
Neil
Re: Neolithic Tiny Basic
if/else/endif does sound worthwhile!
I'm still on my first cup of coffee, but couldn't it start by scanning 'til it finds the endif? Then do a second scan looking for the else... but give up when you reach the endif's location; don't scan the whole of the basic program text.
Alternatively, do a scan that simultaneously searches for else and for endif. But that could get gnarly in a hurry...
Waddaya think of my re-think? (In regard to the second part, I think my re-think stinks!)
-- Jeff
Quote:
it had to scan the whole of the basic program text before it didn't find it
Alternatively, do a scan that simultaneously searches for else and for endif. But that could get gnarly in a hurry...
Waddaya think of my re-think? (In regard to the second part, I think my re-think stinks!)
-- Jeff
In 1988 my 65C02 got six new registers and 44 new full-speed instructions!
https://laughtonelectronics.com/Arcana/ ... mmary.html
https://laughtonelectronics.com/Arcana/ ... mmary.html
- barrym95838
- Posts: 2056
- Joined: 30 Jun 2013
- Location: Sacramento, CA, USA
Re: Neolithic Tiny Basic
TRS-80 Level II BASIC had ELSE but no ENDIF, so you had to keep everything in one numbered line. My 7th grade friend Joe Bridgewater was fond of coming up with complex and confusing nested IF/THEN/ELSEs in a single line, but he always got them to work somehow.
Got a kilobyte lying fallow in your 65xx's memory map? Sprinkle some VTL02C on it and see how it grows on you!
Mike B. (about me) (learning how to github)
Mike B. (about me) (learning how to github)
- BigDumbDinosaur
- Posts: 9427
- Joined: 28 May 2009
- Location: Midwestern USA (JB Pritzker’s dystopia)
- Contact:
Re: Neolithic Tiny Basic
Dr Jefyll wrote:
I'm still on my first cup of coffee...
That’s no excuse!
Quote:
...but couldn't it start by scanning 'til it finds the endif? Then do a second scan looking for the else... but give up when you reach the endif's location; don't scan the whole of the basic program text.
That, to me, sounds like the logical way to handle it. Write the interpreter to require that ELSE has to be bounded by an IF/ENDIF pair. That being the case, if an ELSE is *not* encountered in a statement between IF and ENDIF, it syntactically doesn’t exist in the code block—no need to look ahead on the off-chance there’s an ELSE somewhere. If an ELSE is later encountered after an ENDIF but before another IF, it’s a syntax error.
Quote:
Alternatively, do a scan that simultaneously searches for else and for endif. But that could get gnarly in a hurry... 
Yes it could...I suspect a not-insignificant performance penalty would result. Realistically, that sort of scan needs to occur when the program is written and saved...the save process could do a syntax check. Obviously, saving the program would take a little longer, but runtime performance wouldn’t be affected.
Quote:
Waddaya think of my re-think? (In regard to the second part, I think my re-think stinks!)
Well, as you said, you’re still slurping your first coffee...
BTW, Jeff, what’s your preferred brand of coffee?
x86? We ain't got no x86. We don't NEED no stinking x86!
Re: Neolithic Tiny Basic
Yeah, my first thought was
which works, but because it's trying to find a matching else (i.e. on the same level as the if), if there isn't one, it scans the whole of the text before it gives up and starts looking for endif. Find_pair() matches only one match against one pair; it can't handle two without getting - as you say - really gnarly because it also has to handle while/endwhile and for/next.
So the next plan is to incorporate the pair finding into if(); it will look for either of an else or an endif - at the right level - and continue executing thereafter, which should be correct in either case. This is only for the non-true case; when true it just executes the next line until it meets endif (which just continues) or else (which looks for the matching endif and goes there).
Neil
Code: Select all
char * tmp;
where -= 4; // back to the start of the line
where = find_next_line(where);
if (!compare())
{
tmp = find_pair(where, IF, ELSE);
if (NULL == tmp)
{
where = find_pair(where, IF, ENDIF);
}
else
{
//printf ("next line is: %d\n", get_line(tmp));
where = find_next_line(tmp);
}
}
return where;
}So the next plan is to incorporate the pair finding into if(); it will look for either of an else or an endif - at the right level - and continue executing thereafter, which should be correct in either case. This is only for the non-true case; when true it just executes the next line until it meets endif (which just continues) or else (which looks for the matching endif and goes there).
Neil
- barrym95838
- Posts: 2056
- Joined: 30 Jun 2013
- Location: Sacramento, CA, USA
Re: Neolithic Tiny Basic
BigDumbDinosaur wrote:
That being the case, if an ELSE is *not* encountered in a statement between IF and ENDIF, it syntactically doesn’t exist in the code block—no need to look ahead on the off-chance there’s an ELSE somewhere. If an ELSE is later encountered after an ENDIF but before another IF, it’s a syntax error.
Got a kilobyte lying fallow in your 65xx's memory map? Sprinkle some VTL02C on it and see how it grows on you!
Mike B. (about me) (learning how to github)
Mike B. (about me) (learning how to github)
Re: Neolithic Tiny Basic
BBC Basic in later iterations (after 6502) did allow for block-structured IF-THEN-ELSE-ENDIF as well as the single-line IF-THEN-ELSE, but I don't know exactly how it did it. Example from the manual:
Each IF statement can only have one corresponding ENDIF and, optionally, one ELSE. It is possible to nest statements:
Worth noting that 8-bit BBC Basic was 16k bytes, and the later ones with the more complex grammar were even larger.
Each IF statement can only have one corresponding ENDIF and, optionally, one ELSE. It is possible to nest statements:
Code: Select all
IF S>1000000 THEN
Y=1
IF R=1 THEN
V=1
H=1
ENDIF
ELSE
PRINT "not enough"
ENDIFRe: Neolithic Tiny Basic
That's exactly the approach I'm using. Each if _must_ have an endif, and _may_ have an else. The endif and else must be at the same nesting depth; jumping out between the if and endif will almost certainly break things.
Neil
Neil
Re: Neolithic Tiny Basic
I think I have an approach that works, which handles nested if/else/endif and with the else optional. But I haven't translated it to assembly yet; this is from my C master:
But there is still testing to do; if/else/endif allows for more scope for confusion.
Neil
Code: Select all
> list
10 for q = 1 to 10
20 print q;
30 if q <= 5
40 print "small"
50 else
60 if q < 8
70 print "largeish"
80 else
90 print "large"
100 endif
110 endif
120 next
130 print "done"
> run
1 small
2 small
3 small
4 small
5 small
6 largeish
7 largeish
8 large
9 large
10 large
done
>
Neil
Re: Neolithic Tiny Basic
Yup, it works in assembly too (first time, though it could use some optimisation).
and after running
demonstrating nesting within if/endif and within for/next, and also showing both with and without the optional else.
The bad news is
when I'd like it to finish _before_ $efff, but BB8 has been amusing himself with some optimisations and has many savings I have still to test.
Neil
The bad news is
Code: Select all
f007 : main_99:
f007 : 4c00ef jmp main_1
Neil
Re: Neolithic Tiny Basic
Do you still support the single line version without the endif?
Re: Neolithic Tiny Basic
No, it's always had separate lines for

Neil
- if [condition]
- things to do if the condition is true
- (optional) else
- (optional) things to do if condition is false
- endif
Code: Select all
effd : main_99:
effd : 4cf6ee jmp main_1
Neil
Re: Neolithic Tiny Basic
The latest and greatest, courtesy of some excellent smallifying by BB8 - build size is now only 3,797 bytes. In particular, storeline has been completely rewritten by BB8 to make it half its previous size, and I've chopped a lot out of execute, factoring out a repeated load at four bytes per chop (for a total of 36 bytes) and incidentally made use of the REPTOS macro to save some text space - it generates the same code as it's replacing.
At this point, it's probably worth drawing a line under (except for bugs) and saving the space for a mechanism to save and load a program using a DOS that doesn't yet exist... though I am still contemplating a RND function; low priority because it would just be a 'multiply by a prime number and add another prime' type of thing, easy to do as a gosub anyway. Perhaps more interesting would be a USR function which would call a binary blob...
I haven't made explicit reference, but a program line can be stored even if it makes no program sense. Any text stored within quotes will be stored without compression, so one might use a string (or strings) composed of ascii hex data to store a program before converting it to binary code. You'd have to do some juggling to find the line(s) containing the data, but I think it's doable as things stand.
But I digress... here's the code: Neil
Edit: I've updated the Rough Guide on page 10
At this point, it's probably worth drawing a line under (except for bugs) and saving the space for a mechanism to save and load a program using a DOS that doesn't yet exist... though I am still contemplating a RND function; low priority because it would just be a 'multiply by a prime number and add another prime' type of thing, easy to do as a gosub anyway. Perhaps more interesting would be a USR function which would call a binary blob...
I haven't made explicit reference, but a program line can be stored even if it makes no program sense. Any text stored within quotes will be stored without compression, so one might use a string (or strings) composed of ascii hex data to store a program before converting it to binary code. You'd have to do some juggling to find the line(s) containing the data, but I think it's doable as things stand.
But I digress... here's the code: Neil
Edit: I've updated the Rough Guide on page 10
Re: Neolithic Tiny Basic
Excellent! For me, USR is more useful than RND, because a USR routine could offer a RND if so desired.
Re: Neolithic Tiny Basic
Usr, Ed? What? You mean like this?
That was easier than I though it might be, though it does require building a jsr and ret in the maths variables (hmm, have I missed a jsr (abs)?) but the target address can be any valid expression. I've called an internal routine here; building some code could be, um, interesting... (I mean, of course, is left as an exercise for the student!) though I suppose a routine to return the address of a given line could be helpful.
At the moment there are still around 250 bytes left...
Neil
At the moment there are still around 250 bytes left...
Neil