B4J Library jBasicLib embedded Basic interpreter library

Nearly six years ago I posted the original B4A version of this library that was in fact a port to Java from the original Basic4ppc .Net C# version that I wrote even earlier. Shortly after that I gave up Android development out of disgust with Google and returned to playing with Basic4ppc and C# under Windows.

I now find myself back having to use Android for mobile work and have already posted an updated, polished and reasonably documented version for B4A. I now post here a version that will work with B4J.

Download the zip and before extracting it unblock it by right clicking on it in File Explorer, selecting Properties and checking Unblock at the lower right of the General tab otherwise the CHM help files will need to be individually unblocked.

The zip file contains the library jar and xml files and a relatively trivial demo program that does however show how to load, run and monitor a program. At the top level of the zip you will find a Readme.txt file, you know what to do with it (No! Not that! :)).

EDIT: V2.2 includes a very minor change allowing space characters between the Sub name and the left parenthesis of the parameter list.
Another very minor change allows Resumable Subs to be invoked on the host without error.

EDIT: In light of the slightly renewed interest I've noticed that the B4Script help file is that for the original Basic4ppc version. B4AScript help file now attached is for the BA/B4J versions. The main difference is the Date and Time formatting functions that match Java rather than the .NET original version. Right click and unblock it after downloading it.
 

Attachments

  • jBasicLib_v2.2.zip
    133.5 KB · Views: 400
  • B4AScript.zip
    70.5 KB · Views: 243
Last edited:

agraham

Expert
Licensed User
Longtime User
I think the problem is in LoadCodeAsArray at line 665. This code is picking out every Sub and its line number and assumes the Sub name terminates with a newline, in the case of no parameters when the code line has already been trimmed, or a left parenthesis so the trailing space is stored with the Sub name
Java:
do
{
    ++k;
} while (line.charAt(k) != '\n' && line.charAt(k) != '(');
This should fix it but I don't feel up to exhaustively testing it at the moment
Java:
do
{
    ++k;
} while (line.charAt(k) != '\n' && line.charAt(k) != '(' && line.charAt(k) != ' ');
 

Attachments

  • jBasicLib2.2.zip
    41.4 KB · Views: 319
Last edited:

wl

Well-Known Member
Licensed User
Longtime User
Andy,

Many thanks. I have been going through the code but did not succeed in finding the issue. I will test it and report back. Many thanks !
And especially: take care !!
 

Xfood

Expert
Licensed User
I think the problem is in LoadCodeAsArray at line 665. This code is picking out every Sub and its line number and assumes the Sub name terminates with a newline, in the case of no parameters when the code line has already been trimmed, or a left parenthesis so the trailing space is stored with the Sub name
Java:
do
{
    ++k;
} while (line.charAt(k) != '\n' && line.charAt(k) != '(');
This should fix it but I don't feel up to exhaustively testing it at the moment
Java:
do
{
    ++k;
} while (line.charAt(k) != '\n' && line.charAt(k) != '(' && line.charAt(k) != ' ');

sorry, it's just the library, not the source, you could post the rorgente. Take care of yourself and good healing
 

agraham

Expert
Licensed User
Longtime User
sorry, it's just the library, not the source, you could post the rorgente.
I don't understand :confused:.
The source for version 2.1 is in post #15 above. The mod for version 2.2 and the compiled jar and xml are in post#23 above. There is nothing missing!
 

wl

Well-Known Member
Licensed User
Longtime User
Hi Andy,

Just to give you a big thumbs up ! Your library is great !!

I made a few minor modifications to suit my purpose (external methods call 1 single event with the subname as the first parameter instead of matching a sub with the same name in B4J code, allowing ":" to be used in subnames, adding GetGlobalVarsX and GetLocalVarsX methods to return information in arrays of objects instead of string for easier processing). I also changed the SetArray method to accept the sizes of dimensions1 to 3 because it assumed that the destination array always had a single dimension after the copy (regardless on how it was dimensioned in the first place).

I nearly finished my webserver based on jetty (multiple domains and applications) and with server side scripting using your library (with some external methods for session variables, application variables, maps, matrixes, file uploads etc ...). I also added a possibility to include scripts (outside your library in preprocessing: it merges the scripts together)

By using the step event and creating a secondary script to do debugging I was able to write a webbased debugger (layout is "basic" for now, but my HTML/CSS/JQuery skills are rusty) with a "step", "run to end" and "run to breakpoint" and even allowing for a an inspect and modify variables (on the fly during the debugging session) option.

This was not possible without your excellent library ! Many thanks again !
 

Attachments

  • Untitled.png
    Untitled.png
    72.1 KB · Views: 297
Last edited:

agraham

Expert
Licensed User
Longtime User
By using the step event and creating a secondary script to do debugging I was able to write a webbased debugger (layout is "basic" for now, but my HTML/CSS/JQuery skills are rusty) with a "step", "run to end" and "run to breakpoint" and even allowing for a an inspect and modify variables (on the fly during the debugging session) option.
I'm intrigued. Can you expand on how you implemented this please. In particular how you can modify variables and apparently (from the screenshot) evaluate code all (presumably) within the step event code.
 

wl

Well-Known Member
Licensed User
Longtime User
I'm intrigued. Can you expand on how you implemented this please. In particular how you can modify variables and apparently (from the screenshot) evaluate code all (presumably) within the step event code.

Hi Andy,

The magic is all on your side. My solution is pretty simple.


The breakpoints are implemented as the Stepped event being called each time and there I evaluate whether the step is at one of the linenumbers a I put a breakpoint on.
If a break is needed:
- a new jBasicLib(debugging) instance is being generated and I create a default script to DIM all global and local variables (GetGlobalVars and GetLocalVars) of the code engine into the debugging instance (in the debugging instance they can all be declared as global as the names should be unique).
- Then I make sure the debugging script runs until the last DIM statement at which point I break and set all variables using SetArray and SetGlobalVar (obtaining the values from the code engine from the set of global and local variables).
- The Step then passes control to the debugging screen (websocket page) and waits until the user decides to proceed using you wonderful Lock (Lock.Waitfor).
- When the lock is being freed by the debugging screen the reverse operation is done: copying all variable values from the debugging engine back to the code engine (to Array, global and local variables). That's it basically ..

As said I did some minor modification to facilitate processing.

I initially modified the engine code to accept a debugging instance to be attached. When the debugging instance would run and obtain any of the internal variable values it would be directed to the internal structures of the code instance. This seem to work but seemed more of a hack and in this case I could not do any modification.

The way of work above seems a bit overhead in that I need to copy all variables back and forth, but your library is really fast so I do not notice it on my test applications.

Apart from this I have sys methods that mimic Maps and Matrixes (1 or 2- dimensional redimmable arrays that can be defined everywhere in the application). As these use internal maps I just share these internal maps between the code and debugging engine (so need to copy there).
 

agraham

Expert
Licensed User
Longtime User
Thanks for the information.
a new jBasicLib(debugging) instance
On a new thread I presume.
using Lock (Lock.Waitfor)
That's the only other way I could think of halting within the Step event, apart from a modal dialog as I use in BasicIDE.

Thanks for the donation - very gratefully received. 👍
 

wl

Well-Known Member
Licensed User
Longtime User
Thanks for the information.
On a new thread I presume.
That's the only other way I could think of halting within the Step event, apart from a modal dialog as I use in BasicIDE.

Thanks for the donation - very gratefully received. 👍

Indeed the second engine instance is started on another thread: as the code is running in a web application, the original code is running in the thread of the original request, the second one is running the thread of a websocket (used for the debugger).

Yet again: many thanks for your wonderful library
 

Magma

Expert
Licensed User
Longtime User
Just Excellent... a total solution for those need script into their apps !

B4X:
    Program = "msgbox('test')" &CRLF
    Program = Program & "AppClose"&CRLF

Works !... but a small delay when running these two lines and some times need Kill Process... am I doing something wrong / or forgetting something ?

Is there any license to use it at open source app if needed ? except from credits ?
 

agraham

Expert
Licensed User
Longtime User
but a small delay when running these two lines
You don't say how small the delay but the interpreter has to do several passes over the source code to tokenise it and optimise it so there is some delay loading the code before it can be run. Once stopped the code can be re-run without reloading it so the second invocation will start immediately.
some times need Kill Process..
As you will see from the posts above @wl is using this on a complex multi-threaded web server serving many user requests in parallel with no problems. This code has been wrung out for years and should be rock-solid so I guess whatever causes this is of your own making.
Is there any license to use it at open source app if needed ? except from credits ?
It's entirely my own work so this applies.
Also credits needed.
 

Magma

Expert
Licensed User
Longtime User
@agraham ..I am sure that i am wrong... i i'll process-think it more how i will use it - it was a fast approach by me.

"I guess whatever causes this is of your own making."
Yes ! ofcourse.. you have total right! my mistake..

Thanks for the answer-s !

Your lib is super !
 
Top