Jump to content

Photo

FastBasic - Beta version available

basic compiler interpreter

29 replies to this topic

#1 dmsc OFFLINE  

dmsc

    Moonsweeper

  • 453 posts
  • Location:Viņa del Mar, Chile

Posted Tue Jul 18, 2017 11:46 PM

Hi!

There is a new version of my FastBasic interpreter available, now with optional *floating point* support.

Also, I have written a full language manual, you can browse it at: https://github.com/d...ic-fp/manual.md

Note that the manual is also included in the disk image.

The two files contain the two versions:

- Integer only, currently 8633 bytes, a "?FRE()" minimal program reports 30458 bytes.

- Integer and floating point, currently 9431 bytes, a "?FRE()" minimal program reports 29642 bytes.

Note that FP variables end with a "%" sign, and use the OS mathpack, so FP calculations are slow. Also, you can't have two variables of different type and same name (so "var%" and "var$" are not allowed).

As always, full sources are at github, see https://github.com/d...ee/fastbasic-fpfor the floating point version and https://github.com/d...sic/tree/master for the integer only version.

And you can compile the sources to get the cross-compiler, build from the same sources as the atari compiler.

Enjoy, and report any problem!

Attached Files



#2 peteym5 OFFLINE  

peteym5

    River Patroller

  • 2,378 posts
  • Location:Buffalo NY USA

Posted Wed Jul 19, 2017 8:34 AM

Looks very interesting. Something we can use integers with. I always stated the major problem with Basic being seriously used for games that have many moving objects on those older computers is that you have no choice but to use floating point numbers. That creates a bottle neck when you when to change variables that hold positions of objects and directions they need move. For us that also use assembly, we know the advantage of using bytes, words, and quads to store integers verses using floating point. I played with player/missile multiplexers that manipulate 8 moving objects inside a VBI cycle. Are the integer variables 2 byte only? It should not be too hard to have games using all the play/missile graphics and move at near ML speeds here.


Edited by peteym5, Wed Jul 19, 2017 8:45 AM.


#3 flashjazzcat ONLINE  

flashjazzcat

    Quadrunner

  • 14,183 posts
  • Location:United Kingdom

Posted Wed Jul 19, 2017 1:01 PM

There is a new version of my FastBasic interpreter available, now with optional *floating point* support.


Superb - thanks for this! Editor seems much faster now, although I haven't explored the language much yet. Long ints would be useful but I realise that's a niche requirement (I just think it's nice to handle big numbers without hampering speed with FP).

Really nice project, though, and the speed of development is impressive.

#4 dmsc OFFLINE  

dmsc

    Moonsweeper

  • Topic Starter
  • 453 posts
  • Location:Viņa del Mar, Chile

Posted Wed Jul 19, 2017 1:26 PM

Hi!
 

Superb - thanks for this! Editor seems much faster now, although I haven't explored the language much yet.

I implemented your idea, scrolling using ins-line and del-line. I think it's a little faster, still the speed of text output via E: is not fast. But the big difference is that now the editor uses 0.5k less RAM.

Long ints would be useful but I realise that's a niche requirement (I just think it's nice to handle big numbers without hampering speed with FP).

I opted for FP support as it's a lot smaller thanks to te usage of the OS mathpack. Adding long integers wold need a lot more code.

Really nice project, though, and the speed of development is impressive.

Thanks!. Due to the parser generator, adding to the syntax is not difficult. If you see the sources the difference between integer and FP versions is less than 500 lines, and mostly common routines in the interpreter that call into the mathpack.

 

Looks very interesting. Something we can use integers with. I always stated the major problem with Basic being seriously used for games that have many moving objects on those older computers is that you have no choice but to use floating point numbers. That creates a bottle neck when you when to change variables that hold positions of objects and directions they need move. For us that also use assembly, we know the advantage of using bytes, words, and quads to store integers verses using floating point. I played with player/missile multiplexers that manipulate 8 moving objects inside a VBI cycle. Are the integer variables 2 byte only? It should not be too hard to have games using all the play/missile graphics and move at near ML speeds here.


All integer variables are 16 bit, but you have arrays of bytes and words. Also, the interpreter uses a boolean data type for result of comparisons, those are stored as 8 bit only (1 or 0).

#5 flashjazzcat ONLINE  

flashjazzcat

    Quadrunner

  • 14,183 posts
  • Location:United Kingdom

Posted Wed Jul 19, 2017 1:33 PM

I implemented your idea, scrolling using ins-line and del-line. I think it's a little faster, still the speed of text output via E: is not fast.


The speed-up seems dramatic when using the SVBXE/CON.SYS 80 column driver. As for "E:" - SDX's QUICKED.SYS will probably speed things up further, although I didn't try this yet.
 

I opted for FP support as it's a lot smaller thanks to te usage of the OS mathpack. Adding long integers wold need a lot more code.


Understood. I know long ints bloat the code a little (although this can be reduced by using loops for comparisons, copying, etc), and my preoccupation with them probably stems from spending too many years writing partition editors. :) I'm sure 16-bits will be sufficient 99 per cent of the time anyway.
 

Due to the parser generator, adding to the syntax is not difficult. If you see the sources the difference between integer and FP versions is less than 500 lines, and mostly common routines in the interpreter that call into the mathpack.


Your source code looks well worth studying. Thanks again!

Edited by flashjazzcat, Wed Jul 19, 2017 1:34 PM.


#6 vitoco OFFLINE  

vitoco

    Moonsweeper

  • 312 posts

Posted Wed Jul 19, 2017 4:07 PM

I never liked statement names like -MOVE in TurboBASIC XL because it is not natural and probably makes the parser a little bit more complex. I think in this case it would better to be named as RMOVE (reverse move) or something like that. Of course it could be lost an abbreviation...

 

I haven't test this yet, but what is the result of PRINT 8/3 in the integer version? (truncated, rounded or error?)

 

I guess that the FP version handles both type of variables, but can them be combined in a single expression? If the expression is assigned to an integer variable, which rule applies?



#7 dmsc OFFLINE  

dmsc

    Moonsweeper

  • Topic Starter
  • 453 posts
  • Location:Viņa del Mar, Chile

Posted Wed Jul 19, 2017 8:33 PM

Hi!
 

I never liked statement names like -MOVE in TurboBASIC XL because it is not natural and probably makes the parser a little bit more complex. I think in this case it would better to be named as RMOVE (reverse move) or something like that. Of course it could be lost an abbreviation...

Well, in my parser both are equally easy to parse and would result in the same binary size, just change "-move" with "Rmove" in the file src/basic.syn. Lower case letters are optional, so the statement would be abbreviated to "R.".

I haven't test this yet, but what is the result of PRINT 8/3 in the integer version? (truncated, rounded or error?)
 
I guess that the FP version handles both type of variables, but can them be combined in a single expression? If the expression is assigned to an integer variable, which rule applies?


I tried explaining all of this in the manual, see at https://github.com/d...ic-fp/manual.md

Basically, most operations expect an integer expression, so for example "PLOT 1.3, 5" or "X=3.5" gives a parsing error, you must use "PLOT INT(1.3), 5" or "X%=3.5". The only statement that expects both FP or INT operations is PRINT, in this case the syntax says:

PRINT_ONE:
	EXPR emit TOK_PRINT_NUM PRINT_NEXT
	FP_EXPR emit TOK_PRINT_FP PRINT_NEXT
        STR_EXPR emit TOK_PRINT_STR PRINT_NEXT
This means, to parse PRINT_ONE (one print expression), try tree posibilities:
- first to parse one EXPR (an integer or boolean expression), if success emit a token TOK_PRINT_NUM, then go to parsing PRINT_NEXT (this expects a comma, semicolon or end of statement).
- if not posible, parse one FP_EXPR (a floating point expression), if success emit a token TOK_PRINT_FP and go to parse PRINT_NEXT (same as above)
- at last, parse one STR_EXPR (a string expression), if success emit a token TOK_PRINT_STR and go to parse PRINT_NEXT.

If all the above fail, the entire rule (PRINT_ONE) fails, so the parser backtracks to the rule that called that, etc.

So, the result is that, if it is possible to parse the expression as integer, it will be parsed as such, only if not possible it is parsed as floating point.

The unexpected result of this is that "PRINT 1+8/3" prints 3, but "PRINT 1.+8/3" prints 3.66666666. And, the most confusing of all, "PRINT 8/3*3" prints 6 (the expression is parsed as INT), but "PRINT INT(8/3*3)" prints 8 (the argument to INT() is parsed as floating point).

Note that division gives truncated results (rounded towards 0), and it's warranted that "(A / B) * B + (A MOD B) = A".

#8 dmsc OFFLINE  

dmsc

    Moonsweeper

  • Topic Starter
  • 453 posts
  • Location:Viņa del Mar, Chile

Posted Tue Jul 25, 2017 9:56 PM

Hi!

A new version is available, see the manual at https://github.com/d...ic-fp/manual.md(also included in the ATR, you can see it in your atari via "TYPE MANUAL.TXT").

The main new feature is support for direct compilation to a binary file. In the editor, you can press CONTROL-W to compile to disk, the resulting binary is self-contained.

I also clarified the license to GPL with an added run-time library exception, this means that you can distribute the compiled result of any program written by you under any license of your choosing, either proprietary or copyleft.

After more optimizations, the minimal integer "?FRE()" program reports 30457 bytes free in the IDE, 37531 bytes free compiled, and the floating point version reports 29689 bytes free in the IDE, 37042 bytes free compiled.

Please, I will appreciate any testing of this version, because I plan to do a "1.0" release shortly.

Have fun!

Attached Files



#9 MrFish ONLINE  

MrFish

  • 5,251 posts

Posted Tue Jul 25, 2017 11:41 PM

I don't know if it has been mentioned elsewhere, but do you plan on making a cross-compiler for this language?



#10 dmsc OFFLINE  

dmsc

    Moonsweeper

  • Topic Starter
  • 453 posts
  • Location:Viņa del Mar, Chile

Posted Wed Jul 26, 2017 6:12 AM

Hi!

I don't know if it has been mentioned elsewhere, but do you plan on making a cross-compiler for this language?

It's already available, but currently produces assembly files that can be assembled via cc65. It's included in the source, see this post
http://atariage.com/...eter/?p=3805259

Note that the cross compiler includes an optimization pass, so it produces smaller code.

#11 vitoco OFFLINE  

vitoco

    Moonsweeper

  • 312 posts

Posted Wed Jul 26, 2017 7:09 AM

This is going beyond of what I expected. Wow.

Will you submit this project to ABBUC?

#12 dmsc OFFLINE  

dmsc

    Moonsweeper

  • Topic Starter
  • 453 posts
  • Location:Viņa del Mar, Chile

Posted Wed Jul 26, 2017 7:36 AM

Hi!
 

This is going beyond of what I expected. Wow.

Will you submit this project to ABBUC?


Thanks!

I thought of that, but ABBUC rules prohibit publishing your work before the contest, so it's already out :P . I like the "release early, release often" philosophy.

#13 skr OFFLINE  

skr

    Dragonstomper

  • 650 posts
  • Ready
  • Location:Hamburg

Posted Wed Jul 26, 2017 10:57 AM

Hi!
 

Thanks!

I thought of that, but ABBUC rules prohibit publishing your work before the contest, so it's already out :P . I like the "release early, release often" philosophy.

Not completely "out": If there are major additions/changes, it still might apply. Best is, you ask freetz, who is in charge of the contest.



#14 pusakat OFFLINE  

pusakat

    Space Invader

  • 33 posts
  • Location:Philippines

Posted Tue Aug 1, 2017 5:08 AM

There is a new version of my FastBasic interpreter available, now with optional *floating point* support.

...

...

And you can compile the sources to get the cross-compiler, build from the same sources as the atari compiler.

Enjoy, and report any problem!

 

Hi!  What versions of g++ and cc65 minimum are required to compile these? I get various errors complaining about constexpr being a C++11 keyword, etc. and compilation fails building gen/synt.



#15 dmsc OFFLINE  

dmsc

    Moonsweeper

  • Topic Starter
  • 453 posts
  • Location:Viņa del Mar, Chile

Posted Tue Aug 1, 2017 5:43 AM

Hi!,

Hi!  What versions of g++ and cc65 minimum are required to compile these? I get various errors complaining about constexpr being a C++11 keyword, etc. and compilation fails building gen/synt.

You need gcc 4.8 and higher, or clang 3.3 and higher. You simply need to edit the makefile and add -std=c++11 (or better, -std=c++14 if supported) to the CXXFLAGS variable.

Note that in newer GCC and clang versions c++14 is the default, all current Linux distributions don't need the flag, as well as current mingw-w64 GCC for Windows. I suspect that in newer macos versions, also clang defaults to c++14 at least.

As for cc65, any version from http://cc65.github.io/cc65 will work.

#16 pusakat OFFLINE  

pusakat

    Space Invader

  • 33 posts
  • Location:Philippines

Posted Tue Aug 1, 2017 7:33 AM

You need gcc 4.8 and higher, or clang 3.3 and higher. You simply need to edit the makefile and add -std=c++11 (or better, -std=c++14 if supported) to the CXXFLAGS variable.

 

Thanks! Adding -std=c++14 to CXXFLAGS worked. Am using gcc 5.4.0 on Ubuntu 16.04. 

 

I had tried compiling with -std=c++11 but gen/synt failed with:

src/synt.cc: In function ‘bool p_file(parseState&)’:
src/synt.cc:66:19: error: ‘make_unique’ is not a member of ‘std’
         auto sm = std::make_unique<statemachine<asm_emit>>(p);
                   ^
src/synt.cc:66:57: error: expected primary-expression before ‘>’ token
         auto sm = std::make_unique<statemachine<asm_emit>>(p);
                                                         ^
Makefile:125: recipe for target 'gen/synt' failed
make: *** [gen/synt] Error 1

Using -std=c++14 worked like a charm.

 

Thanks again! This is great!



#17 drac030 OFFLINE  

drac030

    Stargunner

  • 1,836 posts
  • Location:Warszawa, Poland

Posted Wed Sep 6, 2017 9:21 AM

There is a new version of my FastBasic interpreter available, now with optional *floating point* support.


Hi, I think that the carrera3.bas (included in the distribution) when loaded into the editor and run from there crashes the interpreter (int or fp, no matter).

#18 dmsc OFFLINE  

dmsc

    Moonsweeper

  • Topic Starter
  • 453 posts
  • Location:Viņa del Mar, Chile

Posted Fri Sep 8, 2017 6:20 PM

Hi!
 

Hi, I think that the carrera3.bas (included in the distribution) when loaded into the editor and run from there crashes the interpreter (int or fp, no matter).


Yes, currently my carrera3.bas uses too much memory to run within the IDE. You need to compile the program directly to disk (using CONTROL-W key) and run the resulting binary from DOS.

I have tried to reduce the memory footprint so that there is enough left to actually be able to run it from the IDE, but without using the RAM under the OS it will not be easy, as you need to keep the compiler, editor, program source and compiled binary in RAM at the same time, and Carrera3D needs 32kB free to store all track images, PM graphics and gr.7 screen.

#19 drac030 OFFLINE  

drac030

    Stargunner

  • 1,836 posts
  • Location:Warszawa, Poland

Posted Sun Sep 10, 2017 12:13 PM

Yes, currently my carrera3.bas uses too much memory to run within the IDE. You need to compile the program directly to disk (using CONTROL-W key) and run the resulting binary from DOS.


I see. But what about trying to detect that situation and display an error or something like that instead of just crashing the system?

#20 dmsc OFFLINE  

dmsc

    Moonsweeper

  • Topic Starter
  • 453 posts
  • Location:Viņa del Mar, Chile

Posted Sun Sep 10, 2017 9:00 PM

Hi,
 

I see. But what about trying to detect that situation and display an error or something like that instead of just crashing the system?


Yes, I will add a test to carrera3.bas to check if there is enough memory. The program is pretty rough because it was one ten-liner demo, so the memory allocation is hard-coded at start.

#21 drac030 OFFLINE  

drac030

    Stargunner

  • 1,836 posts
  • Location:Warszawa, Poland

Posted Mon Sep 11, 2017 6:33 AM

Yes, I will add a test to carrera3.bas to check if there is enough memory.


Yes, but adding this to the carrera3.bas probably does not prevent any other *.bas program from potentially crashing the system. So by "detecting" I meant adding a check to the interpreter. Because, unless I am missing something, the interpreter has full control on what the carrera3.bas is doing? Or the program contains parts written in machine code which are directly responsible for the crash?

#22 vitoco OFFLINE  

vitoco

    Moonsweeper

  • 312 posts

Posted Mon Sep 11, 2017 7:54 AM

Yes, but adding this to the carrera3.bas probably does not prevent any other *.bas program from potentially crashing the system. So by "detecting" I meant adding a check to the interpreter. Because, unless I am missing something, the interpreter has full control on what the carrera3.bas is doing? Or the program contains parts written in machine code which are directly responsible for the crash?

 

In a plain BASIC program, you should get an ERROR-2 on a DIM statement or so, but when a program thinks that some portion of the memory is available and it uses POKEs and MOVEs statements to manipulate that memory in the way it needs, it'd probably wipe out some of the supporting programs from RAM, like the BASIC runtime lib.

 

Carrera3D was written for TurboBASIC XL and it's own memory structure, using all the free RAM. Probably many of my own tenliners will crash in the same way, and that's not FastBasic fault.

 

When the free RAM window is not the same because the interpreter is another one, you'll get a crash if the program does not check for memory pointers/vectors. It'll probably overwrite the DOS or runtime lib, or you'll just get some garbage on screen.



#23 drac030 OFFLINE  

drac030

    Stargunner

  • 1,836 posts
  • Location:Warszawa, Poland

Posted Mon Sep 11, 2017 8:34 AM

when a program thinks that some portion of the memory is available and it uses POKEs and MOVEs statements to manipulate that memory in the way it needs, it'd probably wipe out some of the supporting programs from RAM, like the BASIC runtime lib.
 
Carrera3D was written for TurboBASIC XL and it's own memory structure, using all the free RAM.


Yes, using the memory in such a way explains much.

#24 dmsc OFFLINE  

dmsc

    Moonsweeper

  • Topic Starter
  • 453 posts
  • Location:Viņa del Mar, Chile

Posted Wed Oct 18, 2017 11:42 AM

Hi!

I published a new version today, with a lot of changes from the last one:
  • Now the floating point and integer versions are integrated in the same source, "FB.COM" is the full version and "FBI.COM" for the integer only version.
  • A lot of optimizations, now FOR loops are a lot faster so the sieve benchmark is at 1329 jiffies (in NTSC, with screen on).
  • Also, the interpreter is still smaller than before, "?FRE()" gives 29803 bytes, or 31093 bytes in the integer only version.
  • Added all standard floating point functions and operators from Atari Basic: "^" (power), ATN(), SQR(), SIN(), COS(), RND(), DEG, RAD. Note that SQR and RND use the fast algorithms from Altirra Basic, SIN and COS use a new minimax implementation that is faster and more accurate than Atari Basic.
  • Fixes for the INPUT statement.
  • Added a "KEY()" function that returns TRUE if a key is pressed.
  • Completed the manual with all the functions and statements.
More information is in the manual at github, also included in the ATR.

You can download the release as an ATR at https://github.com/d...tbasic/releases, there are also cross-compiler binaries for windows and linux.

To use the cross-compiler, you need CC65 (from http://cc65.github.io/cc65/), there is a simple script to automate the build.


Have fun!

Attached Files



#25 VladR OFFLINE  

VladR

    Stargunner

  • 1,564 posts
  • Location:Montana

Posted Wed Oct 18, 2017 5:58 PM

Amazing work ! Sure wish this was available 3 decades ago :)

 

How much free memory is now reported with Integer / compiled ? ~38,200 ?

 

Having option of integer vs default float is obviously huge. But, what are your thoughts on rudimentary support of 8.8 fixed point ? Realistically, for majority of use cases, only add,sub, comparison is needed for 8.8 (e.g. no need for more complex mul/div/etc.). And it's almost as fast as integer.







Also tagged with one or more of these keywords: basic, compiler, interpreter

0 user(s) are browsing this forum

0 members, 0 guests, 0 anonymous users