Jump to content
IGNORED

FastBasic - Summer Release


dmsc

Recommended Posts

As written here

https://web.archive.org/web/20070524044410/http://www3.sympatico.ca/maury/other_stuff/atari_basic.html

 

Atari BASIC, the Bad
So far so good: the new BASIC has simplified syntax and removed barriers. But now it falls flat on it's face. You see, Atari BASIC had no strings. Well OK, that's being a little pedantic, it did have strings, but they were more like C's char arrays.

Under MS you could make strings on the fly, change their lengths, add them together, etc. But in the Atari version you had to predefine all of your strings using the array syntax, and the result was fixed-length. It wasn't a complete loss – there wasn't any need to do garbage collection, and you could make them any length you wanted – but it was still a complete pain in the ass.

What made it really annoying was the syntax for using them. The MS system used a set of three functions to slice up strings:

LEFT$(A$,10)
RIGHT$(A$,10)
MID$(A$, 10, 20)

The Atari version was different, and in some respects a lot simpler:

A$(10,20)

That's it, that single "slicing" command could be used to do all of the things you could do with the three MS commands (although that's true of the MID$ function in MS as well). This might be seen as another one of those generalizations that actually helped out the language. However there's a couple of subtle points that need to be considered.

One is that the "starting point" of the strings were different, so if you were trying to get the leftmost ten characters of a string you had to get 1 to 11. The other difference was that the slicing was based on two absolute positions instead of a position and a length like the MS commands.

Those might not sound like big differences, but they were. Consider the the last MS example above. To properly convert that into the Atari version you'd have to use A$(11,30). So every time you came across a string in one of the programs you were typing in you had to stop and think about it. It wasn't just that the Atari version was harder to work with, it just didn't feel like the MS version.

Worse, Atari BASIC arrays were single dimensional. So whenever you saw a program that used an array of strings in its MS version, you were basically sunk. Of course you could work around these problems, but it always meant spending a lot of time trying to grok what the original version was trying to do and then coming up with an entirely different way to do it.

For instance, in one adventure game I was converting the game constructed an array of strings, each one containing the description for a room. Then the game could print out a room description by simply referring to the string in the right "room number":

1020 PRINT A$(Room)

For the Atari version I had to re-code the entire program using this solution:

1020 GOSUB 10000 + (Room * 10)
[...many more lines...]
10010 PRINT "room one": RETURN
10020 PRINT "room two": RETURN
[etc.]

Link to comment
Share on other sites

As written here, by Bill Wilkinson: https://archive.org/stream/BillWilkinsonArticles/Bill%20Wilkinson%20articles_djvu.txt

 

...Thirdly, the decision to have strings longer than 255 characters (coupled with the tight memory requirements) simply precluded any implementation of string arrays. (In fact, I do not know of any small-machine BASIC that supports string arrays with elements longer than 255 characters.)

 

 

Why doesn’t Atari BASIC have string arrays? I really didn’t want to put this question in, but I wanted to save myself the letters and threatening phone calls. The best reason is that it was a choice of string arrays or syntax checking. (Obviously, I like the choice.) Other rationales include the fact that Atari was aiming for the educational market, where the HP2000 (with 72-character, Atari-style strings) was the de facto standard.

My personal favorite reasons are twofold: (1) anything you can do with string arrays you can also do with long strings (admittedly, sometimes with a little more difficulty) though the reverse is definitely not true; and (2) string arrays are unique to DEC and Microsoft BASIC and do not appear in that form in any other of the more popular languages (e.g., FORTRAN, COBOL, PASCAL, C, FORTH, etc.). Techniques learned with long strings are portable to these other languages: techniques involving string arrays are, at best, difficult to transfer. Finally, long strings as implemented on the Atari have some unique advantages not immediately obvious. I hope to explore some of these advantages in future columns.

 

The primary argument against Atari Basic's string handling is that it isn't Microsoft Basic. Is it still a requirement that people want to port all those type-in Applesoft and C64 programs to the Atari? My feeling is that it's better for a modern-day language to support new code development, and the use cases those new apps require.
Edited by FifthPlayer
Link to comment
Share on other sites

Here's an example of using string arrays in Basic XE. Hopefully this makes sense and I haven't botched the example.

String Arrays in Basic XE

A string array must have two dimensions: the number of strings present (first dimension) and the length of the individual strings (the second dimension). In Basic XE, a string array is denoted by the two dimensions.

DIM DISKARAY$ (100,17)

In this case 100 files, with individual lengths of 17 characters.

In order to access a particular string in the array, a SEMICOLON is used

DISKARAY$(23;) would denote the 23rd string in the array. (Note: begins with 1 and not 0)


For instance, we could have an array of disk titles in a disk catalog. Each entry would be a separate disk and would become an individual file on our catalog data disk. The individual files would contain the file names (directory data) on that disk.

UTILS001.DAT 001
UTILS002.DAT 003
UTILS003.DAT 003
(and so on for as much room as you have on the data disk)

Let's say that you wanted an alphabetical listing of all your utility files so that you can more easily find find a particular file that is somewhere on your collection of utility disks. In order to do that you would read the contents of each file entry on the data disk into a string array that would hold that much data.

Let's further assume that each .DAT file holds anywhere from 1 to 64 individual files and have the normal Dos 2.0s type format of approximately 15 to 17 characters. (Or slightly less, if the file lengths are not included.) When these file names are read into the string array for sorting, the disk identification number must also be included, so you can find the disk having the title that you select.

For our example, let's say that you have 898 individual files with 18 characters per record. This would fit into a string array such as DIM TITLARAY$(1000,18). So that would be 18,000 bytes -- no problem as far as a regular 64K machine. If using an XE (or greater), then the EXTEND command can be used to put the program into extended memory and much of the original (base) 64K can be used for arrays.

Then with Basic XE, you can SORTUP (or alternatively SORTDOWN) the array to provide alaphebetical order. Then print out the listing in the format you choose. Note that this method works great with ATR's and avoids a lot of physical disk swapping. And of course there are several ways to do this, but string arrays provide a pretty straight-forward and convenient method.

-Larry

  • Like 1
Link to comment
Share on other sites

The primary argument against Atari Basic's string handling is that it isn't Microsoft Basic. Is it still a requirement that people want to port all those type-in Applesoft and C64 programs to the Atari? My feeling is that it's better for a modern-day language to support new code development, and the use cases those new apps require.

 

I think there are two roads:

1. make a modern fast Basic with freedom

2. make a modern fast Basic compatible with Atari Basic/Turbo-Basic XL and other contemporary Basics

Link to comment
Share on other sites

I'm surprised to learn that in BASIC XE one cannot simply write DIM ARRAY$(100) to get a 100-element string array. But that approach (element size unknown at the time of declaration) is slow and expensive, I guess (since you need a memory allocator, pointer tables, and garbage collection routines for when things become fragmented). Does any BASIC for the A8 have a full-beans string array implementation (i.e. like BBC BASIC)?

Link to comment
Share on other sites

Memory is an issue in the 8-bit Ataris, so writing DIM ARRAY$(100) might have different meanings:

 

(1) Every element of the array has a predefined size, for example 256.

(2) The size of an element is is variable.

 

In (1), the example would require 25K of RAM, even if the average length of the elements is 15.

 

In (2), the interpreter must manage the memory, probably giving new chunks every the element is assigned, and that would require a garbage collection mechanism, or moving data back and forth, which is obviously slow in our machines.

 

AFAIK, dmsc is working in a simple malloc mechanism, and that will change the way we (mean Atarian BASIC coders) got used to.

 

Link to comment
Share on other sites

Hi!

 

I'm surprised to learn that in BASIC XE one cannot simply write DIM ARRAY$(100) to get a 100-element string array. But that approach (element size unknown at the time of declaration) is slow and expensive, I guess (since you need a memory allocator, pointer tables, and garbage collection routines for when things become fragmented). Does any BASIC for the A8 have a full-beans string array implementation (i.e. like BBC BASIC)?

I know of two, Advan BASIC and MS-BASIC. Both have strings of up to 255 characters and string arrays. MS-BASIC has full garbage-collected strings - the heap is compacted on exhaustion and when calling FRE(). There is a famous bug in C64 basic that makes the compacting time quadratic on the number of previously allocated strings, this can produce pauses in the interpreter of minutes on memory exhaustion.

 

Memory is an issue in the 8-bit Ataris, so writing DIM ARRAY$(100) might have different meanings:

 

(1) Every element of the array has a predefined size, for example 256.

(2) The size of an element is is variable.

 

In (1), the example would require 25K of RAM, even if the average length of the elements is 15.

 

In (2), the interpreter must manage the memory, probably giving new chunks every the element is assigned, and that would require a garbage collection mechanism, or moving data back and forth, which is obviously slow in our machines.

 

AFAIK, dmsc is working in a simple malloc mechanism, and that will change the way we (mean Atarian BASIC coders) got used to.

There is a third possibility, currently used in FastBASIC, allocate string on first assignment. This was simple to implement by storing a 0 at address 0, this is equivalent to a zero length string. So, if you store 0 as the string address, the interpreter can correctly use it as parameter to any function. On assignment, the 0 address is detected and the string is allocated.

 

Yep: method 2 is super expensive, and I would not even advocate its use here. I was just curious if any implementation existed. A C-like approach is preferable, IMO.

In my tests is not as expensive, because I don't plan on using a full garbage-collection (like in MS-BASIC), only call "malloc" and "free" on the string memory at assignment, always copying the string to the new allocated memory.

 

My current implementation (attached alloc.inc) uses 164 bytes for "alloc_memory" and 21 bytes for "free_memory", alloc has linear run-time with the number of allocated blocks, this should not be a problem as I expect only a few blocks in the chain. The memory overhead is two bytes for allocated block, and the length is rounded up to a multiple of 16 to reduce fragmentation.

  • Like 4
Link to comment
Share on other sites

  • 4 weeks later...

MS Basic String handling like in Basic Xl/XE would be nice along with advanced string functions like LEFT$(), MID$(), and RIGHT$(). Equally valuable would be an actual string concatenation operator like STR1$ = STR1$ + STR2$, or a function like STR1$ = CONCAT$(STR1$, STR2$).

 

Apart from its slowness, the greatest weakness of Atari Basic was string handling.

Jumping in the middle here...

 

The "slicing" commands in Atari BASIC were functional, and in some ways more in common with modern systems that generally only have a single substring command.

 

The real problem with them is the off-by-one lengths. LEFT$(10) is not the same as [1,10]! This makes it very easy to introduce errors that can be very difficult to see.

 

I asked Bill Wilkinson about this some time ago, and he was of the opinion there was enough room left on the ROM to include "cover methods" for these commands. That would allow you to use the MS BASIC string commands without changing the entire string system.

 

String arrays are certainly useful too, but I suspect for 90% of the uses, simply having those commands would be enough.

Link to comment
Share on other sites

  • 1 month later...

1. So how do I write out individual characters in a String in FB? Loop and use -MOVE to shift string to the left and obtain first char with ASC(string)? This: A$(10,20) is not supported as I understand.

 

2. I believe the documentation for "MOVE a, b, c is equivalent to .." is not correct, as second parameter to POKE is value, thus a+I denotesaddress, not the value

Link to comment
Share on other sites

Hi archeocomp!

 

1. So how do I write out individual characters in a String in FB? Loop and use -MOVE to shift string to the left and obtain first char with ASC(string)? This: A$(10,20) is not supported as I understand.

Current "released" version does not support sub-strings nor string arrays, test with attached (development) version, the syntax for sub-strings is using brackets: STRING$[sTART,LEN] or STRING$[sTART].

 

You can apply the brackets to any string expression, so the following are valid:

 A$ = "Test Sub String"[6,3]  ' This sets A$ to "Sub"
 B$ = STR$(3.1415)[3]         ' This sets B$ to "1415"
 A$="Hello" : ? A$[3,10]      ' Prints "llo"
Note that sub-string operations are (relatively) slow, as a new string is created and the data is copied. Also, the buffer for sub-strings is reused from STR$ and CHR$, so you can't compare two sub-strings or STR$ with a sub-string.

 

My current sub-strings implementation adds 101 bytes to the IDE, so current integer-only IDE is 8111 bytes size, still less than 8k.

 

2. I believe the documentation for "MOVE a, b, c is equivalent to .." is not correct, as second parameter to POKE is value, thus a+I denotesaddress, not the value

Thanks, the correct expressions are "POKE b+I, PEEK(a+I)", will fix the docs.

 

Have fun!

fastbasic-substr.atr

  • Like 1
Link to comment
Share on other sites

Hi all!

 

After much testing, I decided to publish a new release with all the updates in the last months, v3.5.

 

The mayor change is adding more string capabilities to the language:

- Strings indexing (sub-strings), via the bracket operator: A$[Position, Count] .

The indexing can be applied to any string expression, including constant strings, so you can write expressions like X = Asc("123456") .

- String concatenation, with the =+ assignment operator, like A$ =+ " appended" .

- String arrays. Note that string arrays don't use memory for the cells that are not assigned, so you can DIM a big arrays and fill only some positions.

 

Also, there are some enhancements to the cross-compiler:

- Better error messages on some errors.

- Optimizations to more constant expressions.

 

The new integer IDE is 8156 bytes and the floating-point IDE is 9441 bytes, so the addition of string indexing, concatenation and arrays was only 183 extra bytes.

 

As always, download the new release from https://github.com/dmsc/fastbasic/releases/

  • Like 5
Link to comment
Share on other sites

Hi all!

 

After much testing, I decided to publish a new release with all the updates in the last months, v3.5.

 

The mayor change is adding more string capabilities to the language:

- Strings indexing (sub-strings), via the bracket operator: A$[Position, Count] .

The indexing can be applied to any string expression, including constant strings, so you can write expressions like X = Asc("123456") .

 

I've done some tests and it works nice. It seems that if the first arg is less than 1, the resulting string value is the empty string. I guess that the behavior is the same as when the starting position is greater than the lenght of the string.

 

I was wondering that this notation could be used as an Lvalue to be able to change some part of the string, but the parser didn't like it. I found the reason in the docs:

 

Note that the bracket operator creates a new string and copies the characters from the original string to the new one.

 

So, MOVE statement is still required for that...

 

- String concatenation, with the =+ assignment operator, like A$ =+ " appended" .

 

Interesting...

 

I tried this:

 

A$ = "HELLO"
A$ =+ A$
? A$

 

and just got:

 

HELLOHELLO

so there is buffering somewhere or the lenght of the appended string is added once (probably to check length limits) and the data is copied for that number of bytes. BTW, I was just testing if a variable could be initialized with a repeating string like in Atari BASIC.

 

Another usage test:

 

DEVICE$ = "D"
DRIVE = 1
NAME$ = "MYFILE"
EXT$ = "TXT"
 
FILENAME$ = DEVICE$
IF DRIVE > 1 THEN FILENAME$ =+ STR$(DRIVE)
FILENAME$ =+ ":"
FILENAME$ =+ NAME$
FILENAME$ =+ "."
FILENAME$ =+ EXT$

? FILENAME$

I've checked that the concatenation assignment operator requires a string value, i.e. no automatic cast from numbers, like STR$(DRIVE) instead of just DRIVE from my example, but it could be nice to concate all the simple assignments in a row:

 

 

FILENAME$ =+ ":" + NAME$ + "." + EXT$

 

I'm against the use of the plus sign as a string concatenation operator, but I think this is a special case, because the right side of the assignment operator is NOT an expression, just a list of strings to be concatenated in a sequence to the assigned variable, process which will stop when the variable reaches the max lenght of 255. It could be used any other symbol.

 

 

- String arrays. Note that string arrays don't use memory for the cells that are not assigned, so you can DIM a big arrays and fill only some positions.

 

This is interesting. The manual says:

 

STRING arrays store an string in each element. String arrays use two byte of memory for each element that is not yet assigned (containing empty strings), and 258 bytes for each element with a string assigned.

 

I guessed that those 258 bytes are not continuous but 2 bytes as an element of an array with a pointer to the actual 256 bytes block for the string, and no block is used when the element of the array is not still used.

 

I did this simple test:

DIM A$(10)

FOR I = 0 TO 9
IF I MOD 2 THEN A$(I) = STR$(I)
? ADR(A$(I)),LEN(A$(I)),A$(I)
NEXT I

? "-"

FOR I = 0 TO 9
IF I MOD 2 THEN A$(I) = ""
? ADR(A$(I)),LEN(A$(I)),A$(I)
NEXT I

and the result was:

 

0         0
17266     1         1
0         0
17522     1         3
0         0
17778     1         5
0         0
18034     1         7
0         0
18290     1         9
-
0         0
17266     0
0         0
17522     0
0         0
17778     0
0         0
18034     0
0         0
18290     0

The first loop assigns a string to half of the array elements and prints the memory position of all of them. Those at address zero are not assigned.

The second loop clears the previously assigned values and the memory addess remained. Is there a way to free that block of memory and assign to another one later?

More... if I remove the IF en the second loop and assign the empty string to all the elements, those that didn't have a block of memory assigned, each of them got the following 256 bytes blocks.

 

I've checked that there is no value verification for array indexes just like in numeric arrays. I could read "strings" from elements beyond the limit. Read operations may get garbage, but you could destroy anything if you assign a value to those extra elements.

 

This last "feature" gave me an idea: You could define and empty array string and a word array together, so FastBasic assigns string elements addresses to the numeric array and you could use them as pointers that could be managed.. for example, a sorting routine might change only the pointers and not the string data. This is a simple test:

 

DIM A$(0),P(10)

A$(0) = "ZERO"
A$(1) = "ONE"
A$(2) = "TWO"
A$(3) = "THREE"
A$(4) = "FOUR"
A$(5) = "FIVE"
A$(6) = "SIX"
A$(7) = "SEVEN"
A$( = "EIGHT"
A$(9) = "NINE"

FOR I = 0 TO 8
  FOR J = I+1 TO 9
    IF A$(I) > A$(J)
      TEMP = P(I)
      P(I) = P(J)
      P(J) = TEMP
    ENDIF
  NEXT J
NEXT I

FOR I = 0 TO 9
  ? A$(I)
NEXT I

The result is:

 

EIGHT
FIVE
FOUR
NINE
ONE
SEVEN
SIX
THREE
TWO
ZERO

BTW, there is no CHR$ string function.

 

  • Like 2
Link to comment
Share on other sites

Hi Vitoco!

 

I've done some tests and it works nice. It seems that if the first arg is less than 1, the resulting string value is the empty string. I guess that the behavior is the same as when the starting position is greater than the lenght of the string.

Yes, the args are checked before doing the operation, as I wanted to ensure proper results on all cases, but the option of making A$[-1,4] result in the same as "A$[1,2]" used too many bytes. Byt I properly implemented that the if the second parameter is <1 there are no characters returned, and >255 is the sames as =255.

 

I was wondering that this notation could be used as an Lvalue to be able to change some part of the string, but the parser didn't like it. I found the reason in the docs:

 

So, MOVE statement is still required for that...

Yes, to support using string indexing as lvalues, all the uses should change, for example " INPUT A$[3,5] ". And I realized that MS-BASIC also did not support that.

 

What I was planing to add is using *one* character as lvalue, but I don't know if the syntax would be ok or a new syntax should be used, basically transforming " A$[[3]] = 5 " to " POKE ADR(A$)+3, 5 ". I don't know what syntax would make sense, "A${n}" or "A$[[n]]" or even "ASC(A$,n)" (this is the simpler to implement, using only 8 bytes, but looks strange on an assignment " ASC(A$,4) = 65 " or " INPUT ASC(B$,3) " ).

 

About concatenation:

Interesting...

 

I tried this:

 

A$ = "HELLO"
A$ =+ A$
? A$

and just got:

 

HELLOHELLO
so there is buffering somewhere or the lenght of the appended string is added once (probably to check length limits) and the data is copied for that number of bytes. BTW, I was just testing if a variable could be initialized with a repeating string like in Atari BASIC.

 

Yes, I implemented the appending routine so that "A$ =+ A$" would work, by first copying the length to a temporary variable. You can see the implementation in https://github.com/dmsc/fastbasic/blob/master/src/interp/copystr.asm#L93, it reuses the copy loop from the standard string assignment to save a few bytes.

 

Another usage test:

 

DEVICE$ = "D"
DRIVE = 1
NAME$ = "MYFILE"
EXT$ = "TXT"
 
FILENAME$ = DEVICE$
IF DRIVE > 1 THEN FILENAME$ =+ STR$(DRIVE)
FILENAME$ =+ ":"
FILENAME$ =+ NAME$
FILENAME$ =+ "."
FILENAME$ =+ EXT$

? FILENAME$
I've checked that the concatenation assignment operator requires a string value, i.e. no automatic cast from numbers, like STR$(DRIVE) instead of just DRIVE from my example, but it could be nice to concate all the simple assignments in a row:

 

 

FILENAME$ =+ ":" + NAME$ + "." + EXT$

 

That would be good, bit it is not that simple to implement, as you need the value of "FILENAME$" multiple times, should be compiled to:

LOAD_VAR FILENAME$
CSTRING  ":"
CAT_STR
LOAD_VAR FILENAME$
LOAD_VAR NAME$
CAT_STR
And so on. The parser is too simple right now for that, so there are two possibilities: modify "CAT_STR" to keep the destination string in the stack and add a "POP" operation at the end of the concatenation, so that A$ =+ "1" + B$ would compile to:

LOAD_VAR A$
CSTRING "1"
CAT_STR
LOAD_VAR B$
CAT_STR
POP
... that should add about 15-25 bytes, or to add a new machine code routine to the parser that would store the string variable and another to retrieve that and insert to the code again, to produce the same code as now. This would use about 25 - 35 bytes.

 

All in all, I don't know if it is worth the added complexity or size.

 

I'm against the use of the plus sign as a string concatenation operator, but I think this is a special case, because the right side of the assignment operator is NOT an expression, just a list of strings to be concatenated in a sequence to the assigned variable, process which will stop when the variable reaches the max lenght of 255. It could be used any other symbol.

One possibility is using ";" as the concatenation operator, similar to "PRINT" expressions, but I think that "=+" is the most "recognizable" operator for concatenation.

 

About string arrays:

I did this simple test:

DIM A$(10)

FOR I = 0 TO 9
IF I MOD 2 THEN A$(I) = STR$(I)
? ADR(A$(I)),LEN(A$(I)),A$(I)
NEXT I

? "-"

FOR I = 0 TO 9
IF I MOD 2 THEN A$(I) = ""
? ADR(A$(I)),LEN(A$(I)),A$(I)
NEXT I
and the result was:

 

 

0         0
17266     1         1
0         0
17522     1         3
0         0
17778     1         5
0         0
18034     1         7
0         0
18290     1         9
-
0         0
17266     0
0         0
17522     0
0         0
17778     0
0         0
18034     0
0         0
18290     0
The first loop assigns a string to half of the array elements and prints the memory position of all of them. Those at address zero are not assigned.

The second loop clears the previously assigned values and the memory addess remained. Is there a way to free that block of memory and assign to another one later?

 

Not currently, as I'm using the original heap allocator that simply expands the pointer of last allocated byte, so there is no way to FREE a block alone. As I said before, I have a working alloc/free implementation but it adds 153 bytes and makes the code more complicated, so I don't yet decide if I would use it finally.

 

More... if I remove the IF en the second loop and assign the empty string to all the elements, those that didn't have a block of memory assigned, each of them got the following 256 bytes blocks.

 

I've checked that there is no value verification for array indexes just like in numeric arrays. I could read "strings" from elements beyond the limit. Read operations may get garbage, but you could destroy anything if you assign a value to those extra elements.

 

This last "feature" gave me an idea: You could define and empty array string and a word array together, so FastBasic assigns string elements addresses to the numeric array and you could use them as pointers that could be managed.. for example, a sorting routine might change only the pointers and not the string data. This is a simple test:

 

 

DIM A$(0),P(10)

A$(0) = "ZERO"
A$(1) = "ONE"
A$(2) = "TWO"
A$(3) = "THREE"
A$(4) = "FOUR"
A$(5) = "FIVE"
A$(6) = "SIX"
A$(7) = "SEVEN"
A$( = "EIGHT"
A$(9) = "NINE"

FOR I = 0 TO 8
  FOR J = I+1 TO 9
    IF A$(I) > A$(J)
      TEMP = P(I)
      P(I) = P(J)
      P(J) = TEMP
    ENDIF
  NEXT J
NEXT I

FOR I = 0 TO 9
  ? A$(I)
NEXT I
The result is:

 

 

 

EIGHT
FIVE
FOUR
NINE
ONE
SEVEN
SIX
THREE
TWO
ZERO

 

Good idea, this would be "advance usage of string arrays" :-P

 

BTW, there is no CHR$ string function.

Yes, I did not add that function yet, again it is 21 bytes more :P

 

I will probably include some of the above in the next version, I will try shaving some bytes on the other parts of the IDE.

 

Thanks for the review!

Link to comment
Share on other sites

  • 4 weeks later...

What is the purpose of NppExec plug-in?

What can I do with it (together with FastBasic)?

 

It's a command line execution plug-in. So you can feed it anything that you'd need to for compiling.

It'll also remember your previous issued commands. So you can execute them with a single keystroke.

It can also handle returned compilation errors, and will highlight the corresponding error line in your

code when you click on the error listed in the Notepad++ console output.

Edited by MrFish
  • Like 2
Link to comment
Share on other sites

To compile and run a FastBasic program I need to execute this batch file:

@echo off
setlocal

:: Set initial values
set cc65=C:\cc65\bin\
set fb=fastbasic-fp
set fbpath=%~dp0
set fbname=%~n0

:: Loop over arguments
set prog=
set opts=
set extra=

:readargs
 if "%~1"=="" goto :endargs
 set opt=%1
 if "%opt%"=="-h" call :usage & exit /b
 if "%opt:~0,1%"=="-" set opts=%opts% %~1 & goto :nextarg
 if /i "%~x1"==".asm" set extra=%extra% %~1 & goto :nextarg
 if /i "%~x1"==".o"   set extra=%extra% %~1 & goto :nextarg
 if not "%prog%"=="" call :error specify only one basic file & exit /b
 set prog=%~nx1
 set basfile=%~dpnx1
 set asmfile=%~dpn1.asm
 set xexfile=%~dpn1.xex
 set lblfile=%~dpn1.lbl
:nextarg
 shift
goto :readargs

:endargs

:: Check arguments
if "%prog%"=="" call :error no input file & exit /b
if not exist %basfile% call :error input file '%prog%' does not exists & exit /b
if "%basfile%"=="%asmfile%" call :error input file '%prog%' same as ASM file & exit /b
if "%basfile%"=="%xexfile%" call :error input file '%prog%' same as XEX file & exit /b
if "%basfile%"=="%lblfile%" call :error input file '%prog%' same as LBL file & exit /b

echo Compiling '%prog%' to assembler.
%fbpath%%fb% %opts% %basfile% %asmfile% || exit /b %errorlevel%
echo Assembling '%asmfile%%extra%' to XEX file.
%cc65%cl65 -tatari -C %fbpath%fastbasic.cfg -g %asmfile% %extra% -o %xexfile% -Ln %lblfile% %fbpath%%fb%.lib || exit /b %errorlevel%

Altirra.exe %xexfile%

exit /b

:error
echo %fbname%: error, %*
echo Try '%fbname% -h' for help.'
exit /b

:usage
%fbpath%%fb% -h
exit /b

Is it possible to use it with NppExec so I can execute it with a single keypress?

Link to comment
Share on other sites

I tried NppExec but it doesn't work with 64-bit Notepad++.

 

So I searched and found latest working 32 and 64-bit versions (with manuals):

https://sourceforge.net/projects/npp-plugins/files/NppExec/NppExec%20Plugin%20v0.5.9.9%20dev/

 

I thought I was using the 64-bit version of Notepad++ myself, but apparently not.

I haven't upgraded for a while (still on v6.9); so it was probably before they were

making the 64-bit version.

 

Thanks for the heads up though; I hadn't been checking for updates on NppExec

for a while. One thing to note here though, is that those are not release versions.

But it looks like he has a 2nd release candidate at v0.6 already; so it should be

fairly stable for 64-bit users.

 

I hadn't noticed, but the reason the version on my site doesn't have documentation

is that it's just an update version for v0.5.3. So v0.5.3 proper should be installed,

which has the manual and docs, then the v0.5.3.1 DLL added to get the most

recent update for it.

 

I want to have the release version on my site; so I'll put v0.5.3 and v0.5.3.1 update

up. Then I think I'll add the v0.6 release candidate so they'll be something for

64-bit users.

  • Like 1
Link to comment
Share on other sites

To compile and run a FastBasic program I need to execute this batch file:

@echo off
setlocal

:: Set initial values
set cc65=C:\cc65\bin\
set fb=fastbasic-fp
set fbpath=%~dp0
set fbname=%~n0

:: Loop over arguments
set prog=
set opts=
set extra=

:readargs
 if "%~1"=="" goto :endargs
 set opt=%1
 if "%opt%"=="-h" call :usage & exit /b
 if "%opt:~0,1%"=="-" set opts=%opts% %~1 & goto :nextarg
 if /i "%~x1"==".asm" set extra=%extra% %~1 & goto :nextarg
 if /i "%~x1"==".o"   set extra=%extra% %~1 & goto :nextarg
 if not "%prog%"=="" call :error specify only one basic file & exit /b
 set prog=%~nx1
 set basfile=%~dpnx1
 set asmfile=%~dpn1.asm
 set xexfile=%~dpn1.xex
 set lblfile=%~dpn1.lbl
:nextarg
 shift
goto :readargs

:endargs

:: Check arguments
if "%prog%"=="" call :error no input file & exit /b
if not exist %basfile% call :error input file '%prog%' does not exists & exit /b
if "%basfile%"=="%asmfile%" call :error input file '%prog%' same as ASM file & exit /b
if "%basfile%"=="%xexfile%" call :error input file '%prog%' same as XEX file & exit /b
if "%basfile%"=="%lblfile%" call :error input file '%prog%' same as LBL file & exit /b

echo Compiling '%prog%' to assembler.
%fbpath%%fb% %opts% %basfile% %asmfile% || exit /b %errorlevel%
echo Assembling '%asmfile%%extra%' to XEX file.
%cc65%cl65 -tatari -C %fbpath%fastbasic.cfg -g %asmfile% %extra% -o %xexfile% -Ln %lblfile% %fbpath%%fb%.lib || exit /b %errorlevel%

Altirra.exe %xexfile%

exit /b

:error
echo %fbname%: error, %*
echo Try '%fbname% -h' for help.'
exit /b

:usage
%fbpath%%fb% -h
exit /b

Is it possible to use it with NppExec so I can execute it with a single keypress?

 

I couldn't tell you. I'm not actually using Notepad++ with FastBASIC yet; I've only used it for the basicParser. So all my experience is with that,

and I never needed any long chain of commands to accomplish what I wanted.

 

I suggested it for FastBASIC knowing what it can do with the basicParser, which is also a command line program.

 

I guess the only way to find out is to try it out and see what happens.

Edited by MrFish
  • Like 1
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...