rfo-basic / basic Goto Github PK
View Code? Open in Web Editor NEWThe Repository for the files the Basic project that creates the BASIC! APK for Google Play
The Repository for the files the Basic project that creates the BASIC! APK for Google Play
Forum user tomhatcher asked for READ and DATA as implemented in some flavors of BASIC.
http://rfobasic.freeforums.org/read-data-t1171.html
An implementation should include RESTORE.
Are there other related commands I'm forgetting?
A user has requested the Basic feature of:
ON GOTO , label {,label ....}
be implemented.
Forum member ACF reports:
"After upgrade to release 1.68 I found that gr.get.pixel doesn't return the actual color of the pixel but returns the color of background." I have confirmed the report; ACF got it exactly right.
The problem is in GR.java, method onDraw(Canvas)
. In v01.68, this line was added: if (!Rendering) return; // If Run.java did not ask to render then don't render
It was moved down in v01.69, but it's still there.
This is intended for when the onDraw()
callback gets called as a result of Run.java:execute_gr_render()
calling GR.drawView.postInvalidate()
.
But onDraw() is also called when Run.java:execute_gr_get_pixel()
calls GR.drawView.buildDrawingCache()
.
The drawing cache gets initialized to the background color, but the Rendering
flag is not set, so the graphics objects are never rendered.
Most commands do not check to insure that there is no extraneous (non comment) characters after syntax processing on a command is done. This lack of checking can make debugging some types of coding errors difficult.
If you see a command that does not have a checkEOL(), put it in.....and TEST that change.
A crash report timestamped 11/5/2012 10:01:15 says,
Tried to run the code: select s, list, msg$ Where list was nvar
Sure enough, that crashes every time. Here's a sample program: list.create n, lp list.add lp, 1,2,3,4,5,6,7,8,9,10 select s, lp, "Pick one:", long list get lp, s, selection if long then print "long"; else print "short"; print " press on item "; s; ": "; selection end
It dies on the third line, the select command, in Select.java:Select.getView(). In current code it's line 103, which says: text.setText(list.get(position));
The problem is that Select declares list
as ArrayList<String>
, but the list passed to the select command is numeric. The crash is a cast exception: java.lang.ClassCastException: java.lang.Double cannot be cast to java.lang.CharSequence
Here is a simple "hello world" project generated by AppBuilder. http://mougino.free.fr/helloworld.zip (can be opened in Eclipse)
It compiles fine, resulting APK installs fine on an Android device but the application force closes instantly when run. I tried other more complex projects: idem. I started investigating Basic.java (I'm quite sure it comes from there) but not having the proper test and debug environment, I call someone else's expertise on this, many thanks!
I am adding a "onConsoleTouch" interrupt.
While testing it, I found some bad bug in all interrupts.
The first is that the the interrupts were being tested and acted upon sequentially in RunLoop. If two interrupts occurred at the same time, the last interrupt tested would kill the previous interrupt's goto. I solved this by making the tests if...else if .... else if..... Only one interrupt will be processed per pass and others will not be processed until the previous interrupt resumes.
The second problem happens if the interrupt occurs while skipping over statements in an IF..ELSE block. If skipping then the xxx.resume statement never get executed. I fixed this by pushing an Interrupt Processing item onto the IF-ELSE stack (IfElseStack. See the start of StatementExecuter()).
I will push these changes now. I am continuing to work on Bluetooth from which I got distracted when encountering this problem.
From forum user Dave: onGRtouch
He says v01.71 is not catching his onGRtouch, and that it worked okay in 1.70.
What's happening is that his onGRtouch:
interrupt starts with an IF
. The IfElseStack
is not empty -- it has IEinterrupt
on it. When executeIF()
finds something on the stack, it checks:
if (q != IEexec) {
That needs to be
if ((q != IEexec) && (q != IEinterrupt)) {
otherwise the entire IF block is skipped. In Dave's case, that means it looks like the touch was ignored.
I can make that change easily enough (I have, and it makes Dave's code work again), but I don't know the IF/ELSE code well enough to know if that's all that's needed.
I think it's okay. With other IF/ELSE elements (ELSEIF, ELSE), the IF will already have put its own item on the IfElseStack. The IF is the only one that should have problems.
Paul, does that sound right to you?
Forum user brochi reported very slow response time for byte.position.set with large offset values, like 8 seconds to get to offset two million.
http://rfobasic.freeforums.org/question-related-to-byte-file-i-o-t1275.html
The position_set code loops, reading a byte at a time, to make sure EOF and position are kept up-to-date. Updating the bundle is an expensive operation.
We can improve performance a lot by updating the bundle only once. If we wrap a little careful logic around it, we should be able to use skip instead of read, except for one read to check for EOF. A quick experiment shows a million-byte position.set goes from >5 sec to <5 millisec. Just gotta get the "careful logic" right.
On top of the performance problem, there's something else wrong that I'm having trouble placing (I'm on the road with no debugger!). Make a five-byte file, open it with byte.open, and then do a byte.position.set to byte 10. On a Xoom, the program hangs. Stopping the program is not enough, you have to restart BASIC! to clear the hang. Maybe a blocking read got started? Anyway, I think the hang adds a little weight to this issue.
If you create one of each stack, list, and bundle, the variable that defines them individually is interchangeable with the others.
stack.create n,a
list.create n,b
bundle.create c
d = 1
list.add d,23
stack.push c,44
bundle.put a,"yea",12
I know why this doesn't cause an error.
Yet I believe it should.
Im thinking it would be possible to define a variable as, let's say a stack, by a var.stack
at the end of its name or durring stack.create n,var . checks should be added to each stack command
for validity. this does not mean that a var that describes a stack needs a .stack at the end of it, just that the first time the var is used and wanted to describe a stack. after that we can check if the var used is infact describing a stack or something else
and error.
i hope i described this well enough.
This would also resolve a$ != a . where 'a' should be a string.
Users have requested the ability of attach to and read and write bytes to USB devices. This would be a major development effort. An effort that would require having one or more USB devices to test with.
The Android Developers guide for this feature are at:
http://developer.android.com/guide/topics/connectivity/usb/host.html
At the moment you can not give a string variable to a goto command.
It should be so, that you could set a variable to your string and go to the label your string contains.
This request relies on two issues:
Currently IDE can load programs only from /sdcard it would be an enhancement for the user to choose another place, typically an external sdcard (when /sdcard is used for internal memory)
Android suggests to not hardcode "/sdcard/" but use Environment.getExternalStorageDirectory().getPath() instead
As external sdcard paths can be different from one phone to another: /mnt/extSdCard for Samsung, /sdcard-ext for Motorola, /mnt/ext_card for newer Sony phones, or /mnt/sdcard/externalsd, /mnt/emmc, /Removable/MicroSD, etc. the implementation should propose whatever drive at the root, and when chosen create the "rfo-basic" + "source" + "data" + "databases" folders
Forum user lupoman asked about getting the screen density: http://rfobasic.freeforums.org/how-to-query-for-display-dpi-t1240.html
I replied:
Hi Luis. Good idea. BASIC! doesn't have a command like this now. Android is funny about density, but we ought to be able to come up with something.
As far as I know, BASIC! does everything in absolute pixels, not Android's "density pixels". We'd probably want to translate Android's getDisplayMetrics().density(), which is a scale factor relative to density pixels, to an absolute resolution in dpi.
Rather than opening another issue I will add here that another post somewhere mentioned system uptime. I don't think it was a feature request, but I think it's a reasonable thing for BASIC! to provide. A minor variation would be the time since BASIC! started running. Maybe have "time, time.up, time.running" commands.
These items get me wondering if there is other system info that would be useful.
AddLine() checks for a left-double-quotation-mark and converts it to a simple ASCII double-quotation-mark. Through BASIC! v01.67, the specific character it checked for is hex 0x93. This is the Windows Code Page 1251, or cp1251, encoding. Windows Eclipse defaults to cp1251 for text files.
When the preprocessor was added to v01.68, the Editor.java and AutoRun.java, which each define an AddLine(), were marked as UTF-8 (file-->Properties-->Resource-->Text file encoding). At the same time, perhaps as a side-effect, the 0x93 character got changed to 0xEFBFBD. This is a valid UTF-8 encoding, but not of any flavor of quote.
In v01.69, AddLine() was commented out in Editor and AutoRun, and moved to a new file, AddProgramLine.java. The new file is also marked UTF-8. This version of AddLine(), like the others, has two instances of the check for left-double-quotation-mark. Interestingly enough, the second occurrence was changed to hex 0xE2809C, which is the UTF-8 encoding of the Unicode left-double-quotation-mark, "\u201C". The first occurrence was not fixed, so the second is irrelevant.
This character change has two consequences:
A developer can fix the first problem two ways:
What this "Issue" addresses is how to fix the second problem. I have three specific proposals:
I am not proposing converting guillemets. Programmers are accustomed to using things that look like double-quotation-marks to delimit strings; that's not asking too much.
I have not proposed allowing right-double-quotes to start a string, but I have no objection to it.
And, yes, I am volunteering to fix this before the next BASIC! release.
To be continued (in Comments)...
Often there is a need to make unofficial releases between official Google Play releases. I have been doing this by putting them in Release Notes web pages. I would like others to be able make these releases. The obvious way to do this is to create folder on the BASIC! FTP site. I have created the folder "apk" for this purpose.
The APKs would be named:
Basic_XXXNN.APK where XXX is the release number and NN is the increment.
The first incremental release on V01.71 would be Basic_17101.APK
I think that each of you can use your own keystores to create these intermediate releases.
I would like to test this.
Marc, I would like you kick this off by creating Basic_1711.APK from your Issue #41 fix, put it into "apk" and ask the use with the problem to test it.
Even after Paul fixed the null reference in SUReader.ReadThread.run(), I can crash BASIC! with SU commands.
I'm writing 'ls' to the SUprocess and then reading back the result. If I put in a syntax error that keeps SU.close from running, the SUprocess goes on running after Run has stopped. Then I remove the syntax errors and run some more times. It doesn't take long before an attempt to run crashes.
You'd think that when the "ls" got done the next read would block, but under circumstances I don't understand, sometimes it doesn't.
SUReader uses DataInputStream.readLine(). That seems to be a fragile beast. When I cause a crash, SUReader is still looping, and each read puts a null String reference on the ArrayList.
To fix these, I want to 1) make sure SUprocess really is gone, and 2) try to minimize the impact of readLine() weirdness by cleaning up the interaction with SUprocess and SU_ReadBuffer.
I have made the following changes in Run.java:
theSUReader = null;
SUprocess.destroy();
, then set SUprocess = null;
And over in SUReader.java:
theReadBuffer
, still the same object) -- this is what makes all the new synchronizes in Run have meaningI'm about to commit all that. It looks like a lot, but the explanation is almost longer than the code change just because multi-threading is so finicky.
About "@@9": originally SUReader must have needed a Context, so it had to be started from Run instead of Background. It doesn't use Context (any more?), so I took out the indirection.
A user has requested that secure bluetooth be implemented.
On the forum, in http://rfobasic.freeforums.org/unicode-characters-t1264.html, Antonis and Nicolas talk about getting the numerical value of a Unicode character.
CHR$() and ASCII() are inverse functions, but only for ASCII characters. A Java String is made of 16-bit Unicode characters (UTF-16), and CHR$() returns a one-character Java String. Going back the other way, the ASCII() function discards the upper byte. There is currently no straightforward way to get the value of the whole character. BASIC! needs a true inverse of CHR$().
I don't want to change the ASCII() function because that would break backward-compatibility, and because ASCII() should be defined to return a value in the range defined for ASCII. Instead, I want to add another function that returns the whole 16-bit character value. I've named it UCODE(), as a parallel to ASCII().
The implementation is trivial -- add the "ucode" keyword, then in doMathFunction() copy case MFascii and tweak it:
Unfortunately, the parallel implementation means CHR$(ASCII(""))
and CHR$(UCODE(""))
do not return the same value. The first is the same as CHR$(256)
and the second is the same as CHR$(0)
(because 0x10000 cast to char is 0).
The implementation is tested and ready to commit, but I figured I ought to put the justification and spec for a new BASIC! function on GitHub for review first, lest the horse be caught pushing the cart.
Specifically, f39_downloader.bas fails to open the url.
The most complex code in BASIC! is that code that handles IF/ELSE/ELSEIF/ENDIF.
Now that I have forbidden labels in IF/ELSE blocks I have a report from a user who says that he has a label outside of any IF ELSE block. A label that is getting flagged at run time as being in an IF/ELSE block. This has occurred with the BASIC! version that clears the IF/ELSE stack on GOTO. The IF/ELSE stack is not clear when that label (outside of an IF/ELSE block) is encountered.
Assuming that he is not mistaken then the only way for this to occur is if something is not being popped from the stack when it should be.
I need someone with fresh eyes and a clear head to look at this code,
There have been many requests to have the volume keys change the audio level for the audio commands. I have not been able to find the trick to make this happen. By recommendation has been that the user monitor the volume keys via INKEY$ and make the volume changes using AUDIO.VOLUME
Magicjohn would like a gr.dlcopy array[]
where the display list is copied into a undimensioned array.
I would like to make release 1.71 in the next few days. This means we make only critical code changes until after the release.
If you have any changes that should go into the manual, post an issue in the De Re BASIC! repository.
I will be creating the release notes. Here is what I have so far:
New Stuff:
bt.disconnect
onConsoleTouch:
ConsoleTouch.Resume
f35_bluetooth.bas changed
HTML Form return will no longer exit HTML mode
onTouch: changed to onGRtouch:
Labels inside IF, Else and For blocks now not allowed.
Fixes
Opening Bluetooth in graphics mode
RunTimeError if a numeric list is given to Select
Superuser crashes fixed
Interrupt problems fixed
Anything else?
There have been several requests to implement an expandable list view.
An expandable list view is like the Select command where the items in the select list can be opened to expose sublists.
This should not be difficult to implement.
The tone command will crash after many iterations (around 1000).
The cause is probably running out of memory. The command creates large arrays.
The goal is to make it possible, if not easy, for AppBuilder to generate an APK from Basic.zip
First, I will modify Basic.java so that there is only one version of it. Global flags and variables at the head of the file will determine if it executes as a standard BASIC! Basic.java or an APK Basic.java.
Secondly, I will modify Run.java so that there are no manual edits required to convert standard BASIC! Run.jave to an APK Run.java. This will probably require some of Globals in Editor.java to moved to Basic.java.
The end result will be that the creation of an APK from Basic.zip will require a global search and replace of the project name plus setting some flags and variables in Basic.java.
And, of course, pasting in the APK icons and APK specific files.
A while ago in the forum I asked about allowing the user to disable the preprocessor. The idea was that some users have existing programs that use the leading '_' in variable names. This would let them use the existing programs without editing.
The preprocessor code is nicely contained, so it would not be difficult to wrap its parts in if statements, and we may still want to do that. But we can get the leading '_' back without disabling the preprocessor.
I have code ready that modifies the preprocessor so it treats '_' as a line continuation character ONLY if:
I'm not ready to put this change on the master repo because I broke one case: if a line contains only a space and an underscore, the existing preprocessor treats it as a continuation line. My change calls trim()
on the line, so the leading space gets stripped off. I want to fix this before final commit.
But if you want to review my current code, it is available on my fork. (Unfortunately, it is not on a branch. I am not yet fully gitified.)
paulon0n, I apologize for the truly ugly if
statement I put in your code! It fixes the NUL character bug described below.
I found several bugs in the preprocessor. I fixed the following:
I also realized that the preprocessor triggers have to be used carefully. The pre-increment and post-increment do NOT work with assignment, and you can NOT use pre/post-increment and arithmetic assigment (+=, -=, etc) on the same line. That is, ++a
and b++
work well, as does a += b
, but a += ++b
is a syntax error and a += b++
gives nonsense results. These are not bugs, they're just the way it works. The message to the user is just, "Don't do that."
Paul, if we use my changed code, the manual will need to be updated to allow '_' at the start of variables, like it was before. Whether we use my code or not, I think the manual should tell users to be be careful with the compound operators.
De-Re-Basic issue #19 points out a discrepancy between the manual and the code. When TEXT.OPEN tries to open a file for read but the file doesn't exist, it should set the file index to -1 so the programmer or user can decide what to do about. Instead it gets a Java exception reported as a RuntimeError.
The same thing happens with BYTE.OPEN for read. Scanning the code for all instances of "loadRaw", I found three other similar cases: GR.BITMAP.LOAD, AUDIO.LOAD, and SP.LOAD. They probably all get a RuntimeError (needs verification). The manual for SP.LOAD says the returned ID should be 0; the manual doesn't say what happens for the other two.
I think this has come up before on the basic! forum. There are work arounds presumably, but this problem also plagues the debug popup. I would guess this is caused because gr is not part of the ui thread and is considered as a separate instance then run and so layers on top of it:
(editor)(run)(gr)
so when input is called it is hidden:
(editor)(run + child of run[input])(gr)
not sure of how to fix this, but here it is brought up.
Forum user MrAl suggested an EVAL command that would evaluate a numerical expression: http://rfobasic.freeforums.org/any-eval-function-possible-t1300.html
As you can see from my comments there, it piques my interest. :{)}
Not that there's any shortage of other things to do...
From Der_Wurfel, last week:
I just noticed that if you press the format command in the menu, it capitalizes keywords inside quotation marks. Example: if a$="manualinput"
gets changed to IF a$="manualINPUT"
I presume this should be changed to prevent changing the user's strings.
It has been reported the Bluetooth and Graphics do not work together. The exact nature of the problem is unspecified. The problem is probably of thread interaction. The bluetooth thread is not getting serviced when the graphics thread is active or vice-versa.
Forum user peepssmile has requested multiple windows in the Editor, accessed by tabs.
There are some UI design questions to resolve:
I just updated the debugger popup, which now allows the user to swap between views. I noticed a bug( maybe) with the ui thread creating multiple instances of runloop and doinbackground until basic crashes. looking at what i have added this shouldn't happen, but then again im new to java and dont really know how threading works in it yet. so any help figureing this out would be helpful.
[edit] ui thread fixed, i needed the swap loop to sleep
I have one update left to complete for the debugger, i plan to add the ability to allow the user to change the watched vars, list, stack, array, and bundle right in the debug dialog.
Here are the important lines from the Stack Trace:
Caused by: android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
at android.view.ViewRootImpl.checkThread(ViewRootImpl.java:4267)
at android.view.ViewRootImpl.requestLayout(ViewRootImpl.java:842)
at android.view.View.requestLayout(View.java:12815)
at android.view.View.setLayoutParams(View.java:8358)
at android.view.WindowManagerImpl.updateViewLayout(WindowManagerImpl.java:312)
at android.view.WindowManagerImpl$CompatModeWrapper.updateViewLayout(WindowManagerImpl.java:145)
at android.app.Activity.onWindowAttributesChanged(Activity.java:2235)
at android.view.Window.setAttributes(Window.java:785)
at com.rfo.basic.GR$DrawView.onDraw(GR.java:418)
at android.view.View.draw(View.java:11118)
at android.view.View.buildDrawingCache(View.java:10835)
at android.view.View.buildDrawingCache(View.java:10675)
at com.rfo.basic.Run.execute_gr_save(Run.java:11766)
at com.rfo.basic.Run.executeGR(Run.java:9982)
at com.rfo.basic.Run.StatementExecuter(Run.java:2902)
at com.rfo.basic.Run.access$4(Run.java:2738)
at com.rfo.basic.Run$Background.RunLoop(Run.java:1654)
at com.rfo.basic.Run$Background.doInBackground(Run.java:1599)
at com.rfo.basic.Run$Background.doInBackground(Run.java:1)
What happened:
Run started
The first command executed was gr.save.
execute_gr_save() should not have been called because graphics was not opened.
It should not have been called but it was. It was and it caused a crash.
I often see crash reports like this. A statement crashes in an impossible way. One thing I often see are cases where there is an "index out bound" error but two or three statements before the line that crashed, the index was verified to be in bound.
It is like Run is continuing to run a previous program rather that starting with a fresh program.
Even stranger, this user created this exact same crash four times in a one hour period.
I am hoping that some fresh eyes and ideas can help to solve the mystery.
The handling of IF and FOR use stacks to control the process. If the user exits an IF or FOR block then the stack entry remains forever. Do this enough and the process will run out of memory.
The GOTO code should prune the stacks. But which stack should it prune? Logically both.
What if the GOTO is going to something inside the same IF or FOR block? Maybe this is a low enough probability that it can be handled by a warning in the manual.
now this could be intended, i forgot to look at the documentation, but bundle.keys creates a new list regardless of it being specified. easy enough to fix if its not intended.
bundle.copy is disabled, im sure this was something Paul wanted to do but got sidetracked.
Debugger upgrade
right now the button that say's "full debugger" does nothing it will eventually be a swticher so you can access the other dialogs without hard commands. Im going to add some more features, that are on the advanced side. i want to add a basic! shell or console that does immediate running of a line upon done(while the program is running) for real-time testing / prototypin, note: not sure if its possible. I also want to add the ability to change the values of scalars,array's, list's, stack's, and bundle's by touching there line in each debugger dialog. I want to add the ability to switch the watched scalars, list, stack, array, bundle in each of there relative dialogs so switching doesn't have to be hard coded.
if (mmSocket != null) mmSocket.connect();
else connectionFailed();
After calling connectionFailed(), the function goes on to call connected() with mmSocket null. This would cause precisely the crash seen in the reports.
I'm not sure why the constructor is allowed to get a null mmSocket without throwing an exception, but that's the way the the original BluetoothChat sample code was written. Paul added the check for null mmSocket, and my tweak is to make sure the run() function returns without calling connected().
I tightened up the inter-thread communication. Specifically, I made the field mState and the method getState() both private. The Bluetooth methods in the Run class can look only at Run.bt_state, set by messages to the Run.Handler (except Run.execute_BT_open, which initializes Run.bt_state). This forces things based on BT.STATUS to run in order.
BT.STATUS wouldn't work until after the entire Bluetooth set-up was established, so following BT.OPEN immediately with BT.STATUS usually got a runtime error. I fixed it so BT.STATUS returns -1 if Bluetooth is not yet up and running.
That means you can run BT.STATUS even without a BT.OPEN call, or even if the phone or tablet does not support Bluetooth.
I don't think Run.execute_BT_status() and Run.execute_BT_open() can ever run at the same time, but it would be very bad if they did, so I put "synchronize" on them both. This is mostly to protect the field mChatService.
This makes btCSrunning meaningless, so I took it out. That makes a change in GR.java, too.
Perhaps ironically, taking out the publishProgress indirection probably makes the "synchronize" on BT_status and BT_run unnecessary.
If Bluetooth is already enabled, BT_open does not need to ask the BluetoothAdapter to enable it. A side-effect of not asking: if GR is open, the GR.doEnableBT sequence does not happen.
checkEOL (of course!) - on all BT commands except BT.write (same reason it's not on Print) and BT.onreadready.resume (because I intend to get all the resumes at once in doResume()).
The method gr_getRect(Bundle b) is used to get the boundary rectangle of an object. It does not get the boundary rectangle of drawn text. It can and should.
The gr_getRect(Bundle b) is used by the gr.collision function for collision detection.
The execute_gr_get_texbounds() method shows how to get a text object's boundary rectangle.
A user has requested that video be implemented. The problem with implementing video is that video uses the Media Player which is also used for the Audio commands. The two features will need to be integrated. Implementing Media Player was tricky because of the strange implementation of the feature in the Android OS. I suspect that adding video will be a real headache.
HTML should not closed when "FOR:" received. The use should be able to go back to the form.
Forum user MrAl reports that BASIC! won't allow a sign on the exponent of a numeric literal. MrAl is right. BASIC! reports a JavaNumberFormatException
.
BASIC! usually treats signs as unary operators, not as part of a number. The getNumber()
function either has do a recursive evaluation or special-case a sign after an 'E'. There is precedent (e.g., READ.DATA
) for special-casing signs.
While we're in there, if we want to be fussy, we should change getNumber()
so more than one decimal point is reported as a syntax error without the Java exception.
Examples:
a=1.2e-3
a=1.2e+3
a=1.2.3
all get a JavaNumberFormatException
.
For intermediate releases, skip steps 3,4,5,6 and 9.
Around line 460 of GR.java,
if (!Rendering) return;
Cures one problem. Creates another.
The program:
gr.open 255,255,255,255
gr.color 255,0,0,255,1
gr.render
do
until 0
Usually but not always, flashes the blue rectangle and then is disappears. This is cause by a second call to GR.onDraw() with Rendering = false. Because it is false, the invalidated canvas does not get re-drawn.
The problem that was solved by adding the flag was objects that were getting drawing into the display list were rendering before gr.render was called.
I guess we are going to have to find a way to solve the original problems without creating this new problem.
Any ideas?
Let's aim for making release 1.72 in the next week or so. If you have any work in progress please finish it or postpone it.
This is a list of the enhancements and fixes. I am sure there are more. Please edit this post to help complete it.
Enhancements.
Base Drive feature.
GR.SCREEN Density feature. Documented in De Re BASIC!? <-
De-Re-Basic Issue 24, closed
UCODE(). Documented in De Re BASIC!? <-
De-Re-Basic Issue 23, closed
Text and Byte Position setting performance has been improved by a factor of 3.
Fixes:
GR running, rendering, close series of issue
Non handled interrupts will no longer block new interrupts.
F11_graphics_touch.bas fixed
F32_tcp_ip_sockets.bas fixed.
f34_remote_camera.bas fixed
f35_bluetooth.bas fixed
Opening non existent file now returns -1 as described in the manual.
Super User fixes (Specifically what will the user see?)
BASIC! no longer closes HTML when FOR: message received.
Read from Raw resource fixed
Numeric literal constants can have signed exponents.
Words inside quotes:
if a$="manualinput"
gets changed to
IF a$="manualINPUT"
Labels that start with keywords:
FORmula:
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.