X16 BASIC

Feel free to talk about any other retro stuff here including Commodore, Sinclair, Atari, Amstrad, Apple... the list goes on!
rje
Posts: 1263
Joined: Mon Apr 27, 2020 10:00 pm
Location: Dallas Area

X16 BASIC

Post by rje »


This thread is inspired from the "full of nerdy goodness" discussion here: 


 


  • Fits in 16K 


  • Integer BASIC (2 byte or 4 byte?)


  • Long identifier names (how long?  8 chars?  16 chars?  other?)


  • Line numbers ONLY for ordering code (and can be invisible in an editor).


  • Labels for managing GOTO.


  • GOSUB replaced by named subroutines.


  • Block notation, While, Do Until, If Then Else Endif.


  • Sound and graphics commands.


  • Existing "DOS" commands.


  • Most or all of the existing BASIC 2.0 commands (?)


 

 

I know I know... the proper way to do this is to actually WRITE CODE instead of do armchair engineering.  But my current project is stalled while I try to relearn how pointers REALLY work in C and why a function can find an entity in a list, assign a parameter pointer to the found entity, but then that pointer gets lost to the caller.

Answer: it's because I haven't coded in C in decades, that's why.

 

 

 

 

 

 

TomXP411
Posts: 1762
Joined: Tue May 19, 2020 8:49 pm

X16 BASIC

Post by TomXP411 »



On 12/21/2020 at 2:10 PM, rje said:




I know I know... the proper way to do this is to actually WRITE CODE instead of do armchair engineering



Actually, the proper way to do it is to... do the engineering. Then write code.  Like you're doing. ?

I've got way too many projects where I jumped into writing code, realized later that I didn't properly engineer it, and then had to re-write the program after an engineering pass. My terminal program, which is still not complete, is a classic example. 

Having said all that... I think trying to design a new interpreter at this point is counterproductive, as one is already in development. Instead of building another interpreter, it might be more useful to design a compiler to run structured BASIC code on the Commander. The compiler itself can be as large as needed, but I think it's still reasonable to expect the compiled code to fit in the 32K of program RAM, maybe allowing the 8K banks to be used for variable storage. 

 

 

paulscottrobson
Posts: 300
Joined: Tue Sep 22, 2020 6:43 pm

X16 BASIC

Post by paulscottrobson »



On 12/21/2020 at 10:10 PM, rje said:




Fits in 16K 




  • Integer BASIC (2 byte or 4 byte?)


  • Long identifier names (how long?  8 chars?  16 chars?  other?)


  • Line numbers ONLY for ordering code (and can be invisible in an editor).


  • Labels for managing GOTO.


  • GOSUB replaced by named subroutines.


  • Block notation, While, Do Until, If Then Else Endif.


  • Sound and graphics commands.


  • Existing "DOS" commands.


  • Most or all of the existing BASIC 2.0 commands (?)







  • 4 byte. It gives you the extra flexibility and you can do fixed point maths if you really want it. A non authentic 32 bit multiplier in Vera would make a difference. Other things it barely matters.


  • Once you get beyond about 6 characters it doesn't really matter. To get efficiency you have to build a hash table, probably using linked lists.


  • Dump the labels. You don't need them with decent structures and it encourages poor practice.


  • Compatibility doesn't matter much. Semantically it's better to have Data typed, so you have to put text in strings rather than allowing DATA 32,HELLO,42 which the tokeniser loves.


  • Named procedures with parameters and locals aren't difficult and are way more readable.


  • Inline assembler (https://central.kaserver5.org/Kasoft/Typeset/BBC/Ch43.html). Actually implemented one of these, it's about 1k, half of which is a data table. The 65C02 is fairly orthogonal (except for STZ which was just plonked anywhere !)


  • BBC Basic indirection operators.


rje
Posts: 1263
Joined: Mon Apr 27, 2020 10:00 pm
Location: Dallas Area

X16 BASIC

Post by rje »



6 hours ago, paulscottrobson said:





  • 4 byte. It gives you the extra flexibility and you can do fixed point maths if you really want it. A non authentic 32 bit multiplier in Vera would make a difference. Other things it barely matters.




I do prefer long ints.  So unqualified AGREE.


Quote





  • Once you get beyond about 6 characters it doesn't really matter. To get efficiency you have to build a hash table, probably using linked lists.




Reasonable.  "Lox" uses closed-hashing with probing (and so does the old Perl2 from 1988 for that matter -- see hfetch and hstore in https://github.com/bobbyjim/perl2/blob/master/src/hash.c, or my reduction of it at https://github.com/bobbyjim/x16-8sh/blob/main/phash/hash.c), but separate chaining works of course.


Quote





  • Dump the labels. You don't need them with decent structures and it encourages poor practice.




I think GOTO is useful in constrained systems, and I'm not so worried about practice.


Quote





  • Compatibility doesn't matter much. Semantically it's better to have Data typed, so you have to put text in strings rather than allowing DATA 32,HELLO,42 which the tokeniser loves.




Agreed, and hadn't thought about what the tokenizer wants or doesn't want.  In my code, the size of the interpreter is the biggest threat, since the tokenizer and compiler can be separate programs.


Quote





  • Named procedures with parameters and locals aren't difficult and are way more readable.




Love it.


Quote





  • Inline assembler (https://central.kaserver5.org/Kasoft/Typeset/BBC/Ch43.html). Actually implemented one of these, it's about 1k, half of which is a data table. The 65C02 is fairly orthogonal (except for STZ which was just plonked anywhere !)




I would like this.


Quote





  • BBC Basic indirection operators.




Something like a PTR type?  Nice and powerful.

rje
Posts: 1263
Joined: Mon Apr 27, 2020 10:00 pm
Location: Dallas Area

X16 BASIC

Post by rje »



On 12/21/2020 at 8:12 PM, TomXP411 said:




I think trying to design a new interpreter at this point is counterproductive, as one is already in development.



That's true.  But, talking it over helps me think about the topic.

paulscottrobson
Posts: 300
Joined: Tue Sep 22, 2020 6:43 pm

X16 BASIC

Post by paulscottrobson »



1 hour ago, rje said:




Something like a PTR type?  Nice and powerful.



Much better than Peek etc.  so instead of PEEK(A+4) you can write A?4 or ?(A+4) - as l-expr and r-expr , so you can write ?&9F27 = 42 for example. ! is the same except it works with long ints. You can go the full hog and dump strings and make a monotype BASIC using a similar $ operator so c$4 = "Hello" is the same as C's strcpy(c+4,"Hello"). This is really neat and makes things much easier but you lose all the protection with strings, so if you do c = &1100 ; $c = "Hello" it writes the ASCIIZ string int &1100-&1105 whatever is in there. You can if you want type track so that the language does "xx">"aa" directly rather than using strmp() like C or Java. It doesn't really matter.

If you are mostly writing games though, it's like Floats.  You just don't need them. If you want to do fractional things like you might in (say) Asteroids you can just to it as 8 bit fixed point, then rather than Int being horribly complex it's just x >> 8 ; and shift operations are way lighter than divide, especially if you optimise them.

You also lose all the garbage collection and all the other problems ; strings are a messier on locals as well. There's a lot to be said for monotype languages like BCPL (though BCPL's syntax is horrible).

rje
Posts: 1263
Joined: Mon Apr 27, 2020 10:00 pm
Location: Dallas Area

X16 BASIC

Post by rje »


Oh gosh I am SO ON BOARD with address notation. 

I'd feel VERY at home if it used the splat and amp operators: &$9f61 = *(A+4).  Oooh, gives me goosebumps it does. 

One Data Type To Rule Them All (e.g. "everything is a Word") boggles my mind.  I tend to think in the other direction, where the holding object is all things to all people, tree-huggingly hippie-ish, who cares because memory is free, etc etc.  That sort of thinking doesn't work as well in limited RAM platforms.

As you mentioned, it all depends on what you're expecting to do.  If I want a "shell" that can pipe stuff around and handle "scripts" with (very) tight limitations, then I might be able to squeeze some fancy stuff in there.  But if I wrote an All-purpose Symbolic Instruction Code, then I have to loosen my grip on a lot of shellish features.  And if I wanted something that hugged itself closer to the bare metal, I'd get rid of other precious things too (GC).

User avatar
desertfish
Posts: 1078
Joined: Tue Aug 25, 2020 8:27 pm
Location: Netherlands

X16 BASIC

Post by desertfish »


While dealing with pointers is still a bit iffy in Prog8. There is however memory mapped variables and the direct memory access operator '@'.

&ubyte BGCOL0 = $d021 ; screen color register on the C64
BGCOL0 = 7 ; set color to yellow

@($d021) = 7 ; set 7 directly to memory location
color = @($d021) ; read value directly from memory location

I'm still kinda new at language design, but I find it interesting that we're coming up with more or less the same concept here!

TomXP411
Posts: 1762
Joined: Tue May 19, 2020 8:49 pm

X16 BASIC

Post by TomXP411 »



3 hours ago, rje said:




Oh gosh I am SO ON BOARD with address notation



The concept is fine, but BASIC has never been about using symbols in that way. Other than the sigils ($, %, #, !), BASIC generally doesn't use symbols to modify literals or variables in an expression. This is because BASIC is supposed to be a beginner's language, and symbol syntax is confusing. (This is a big reason beginners hate C.)

Having said that... we've moved past pointers. C and C++ needed them to support passing variable references around, but that is generally unneeded in a language that supports proper reference handling. 

Here's a more BASIC-friendly way of handling it:


  • VARPTR(variable) returns the address of a variable's data. For complex types, this returns the place on the heap that the data lives. For simple types (aka float or int), this returns the address on the stack or data segment. This is already part of later editions of BASIC, including BASIC-80 on CP/M and Advanced BASIC on PC.


    • x=VARPTR(A$) gets the address of the A$ string data.


    • POKE(VARPTR(A$)+3,64) would set the third character of A$ to @. The first byte is the length, so VARPTR(A$)+1 returns the first character element.




  • SET var1=var2 copies a reference. This is a shallow copy, so the underlying data is not duplicated. ie: modifying an element in Red_Porche also modifies the same element in MyCar.) Visual BASIC assignes objects with this syntax.


    • SET MyCar=Red_Porche




  • SET var1=NEW(type) would create a new instance of a compound type and assign that to var1.


  • POKEF/POKEI/POKES(addr,value) sets a float, int, or string value at the specified address. This saves the raw, encoded value.


    • POKEF encodes a 40 bit floating point value with the exponent in the first byte and the mantissa in the remaining bytes


    • POKEI encodes a 16 bit integer value in Little-Endian format. 


    • POKES writes a string in BASIC compatible format. Byte 0 is the length and up to 255 characters of data.




  • PEEKF/PEEKI/PEEKS(addr) returns a Float, Integer, or String located at address addr.


 

paulscottrobson
Posts: 300
Joined: Tue Sep 22, 2020 6:43 pm

X16 BASIC

Post by paulscottrobson »



22 hours ago, desertfish said:




While dealing with pointers is still a bit iffy in Prog8. There is however memory mapped variables and the direct memory access operator '@'.




&ubyte BGCOL0 = $d021 ; screen color register on the C64
BGCOL0 = 7 ; set color to yellow

@($d021) = 7 ; set 7 directly to memory location
color = @($d021) ; read value directly from memory location



I'm still kinda new at language design, but I find it interesting that we're coming up with more or less the same concept here!



Yes - it goes back to BCPL really but the first place I came across it in BASIC was the SC/MP NIBL Basic

Post Reply