QB64.org Forum

Active Forums => QB64 Discussion => Topic started by: SMcNeill on November 29, 2019, 04:14:56 am

Title: A few pushes to the Development build
Post by: SMcNeill on November 29, 2019, 04:14:56 am
Over the last several days, I've been doing a little work with pushing changes to QB64, and I wanted to take a moment to just document what's altered so folks can be aware of things.

1) I fixed the issue with $IF UNDEFINED (as described here: https://www.qb64.org/forum/index.php?topic=1910.msg111352#msg111352)

2) I expanded functionality with _PUTIMAGE so it can now be used with the same _SOURCE and _DEST.  Before, it would toss an error for us; now it works with no issue at all.  _PUTIMAGE (100,100)-(200,200), 0, 0, (200,200)-(300,300) will copy a section from the active screen and then paste it somewhere else over that same screen.

3) I replaced our _CONSOLEFONT with a blank stub that does nothing, by default.  The function calls to change the font and font size with the console in Windows requires modern API calls, and won't work with any version of Windows older than Vista.  By enabling the command be default, it means that QB64 would no longer work on Windows XP, Windows 2000, or any versions older than Windows Vista...   I don't think anyone really wants to obsolete older OSes from what we work with, so this command has been replaced with a simple blank stub.

IF you're one of the few people who run a version of Windows Vista, or newer, and who wants to be able to change font and font size in the console, then all you need to do is comment out the stub, uncomment out the working routine, and then run the batch file "purge_libqb_only.bat" so QB64 will automatically rebuild the library to take advantage of the routine you just put back in there.

The framework is there for folks who want to use it, with a simple 1, 2, 3 change, while it keeps us from failing to compile and run on older Windows machines.  ;)

Title: Re: A few pushes to the Development build
Post by: SMcNeill on December 04, 2019, 01:05:53 pm
Pushed an option into the IDE today so you can toggle to Ignore Warnings on and off.   (Variable not defined, or CONST name already in use warnings.)
Title: Re: A few pushes to the Development build
Post by: RhoSigma on December 04, 2019, 01:09:44 pm
Funny, an "anti OPTION _EXPLICIT" switch, I like it :)
Title: Re: A few pushes to the Development build
Post by: SMcNeill on December 04, 2019, 01:18:01 pm
Funny, an "anti OPTION _EXPLICIT" switch, I like it :)

We’re trying to get everything ready for the next stable release of QB64, and this is one of the features that “Steve’s Repo” has that I definitely wanted to get into QB64 by the next release.  ;D
Title: Re: A few pushes to the Development build
Post by: RhoSigma on December 04, 2019, 01:47:58 pm
We’re trying to get everything ready for the next stable release of QB64, and this is one of the features that “Steve’s Repo” has that I definitely wanted to get into QB64 by the next release.  ;D

Well, then I've something to look at too for the next stable release. After the run with the BIN$ function in the other place, I did also try the reverse part and found some missings for &B prefixed number strings.

We can use it in regular formulas (3 + &B1101 etc.), this is already handled by qb64.bas and is there since SDL days. We can also use it as VAL(&B0101) now, but whoever made the VAL addition overlooked some other uses.

INPUT a& => does accept &H, &O but not &B => see libqb.cpp function hexoct2uint64()

INPUT #fid, a& => does read &H, &O but not &B => see libqb.cpp function n_inputnumberfromfile()

DATA => does read &H, &O but not &B => see libqb.cpp function n_inputnumberfromdata()

FOR i% = 1 TO 3
    READ a&
    PRINT a&
NEXT i%
END
DATA &Hff,&O377,&B11111111

And by a quick search for "oct" it appeared, there are several more functions which have the hex/oct conversion in it but not the bin conversion. Maybe It would be a good idea to see if all these code redundancies can be pulled together in one conversion routine, which then can be called from the appropriate places.
Title: Re: A few pushes to the Development build
Post by: hanness on December 05, 2019, 12:52:28 pm
Here is my list of items I'd love to still see addressed prior to the release of the next stable release:

Issue #1: SLEEP command with a specified sleep time does not work in console.

Sample code:

NOTE: Run the code below twice:

First Run: Run it as is and note that the sleep command works fine.

Second Run: Uncomment the lines that are currently commented out to run the program in a console. Note that the program will never advance past the sleep command until a key is pressed.


---------------------------------------
' $CONSOLE:ONLY
' _DEST _CONSOLE: _SOURCE _CONSOLE

PRINT "If the SLEEP command is working, then the program should continue"
PRINT "in 5 seconds without any need to press a key...."
PRINT
SLEEP 5
PRINT "If we arrive here <without pressing a key> then SLEEP is working,"
PRINT "otherwise it is not working."
---------------------------------------

Issue #2: Whether due to changes made by Microsoft or whatever reason, many of the $VERSIONINFO items are not working.

Sample code:

---------------------------------------
$VERSIONINFO:CompanyName=My Company
$VERSIONINFO:FILEVERSION#=1,2,3,4
$VERSIONINFO:ProductName=My QB64 App
$VERSIONINFO:LegalCopyright=(c) 2019 by My Company
---------------------------------------

Of the above items, the only one that will display the information specified is "FILEVERSION". There may well be others that also don't work, the above is only a sampling, not an all inclusive list.

Issue #3: I know that the built-in help may not be finalized until the next release is finalized, but I thought that I would simply note that I'm not seeing help for the following items as yet. There may be others, but these are just the ones I tried to lookup and was unable to locate:

_consoleinput
_cinp
_consolefont

Title: Re: A few pushes to the Development build
Post by: SMcNeill on December 05, 2019, 03:33:35 pm
Here is my list of items I'd love to still see addressed prior to the release of the next stable release:

Issue #1: SLEEP command with a specified sleep time does not work in console.

Sample code:

NOTE: Run the code below twice:

First Run: Run it as is and note that the sleep command works fine.

Second Run: Uncomment the lines that are currently commented out to run the program in a console. Note that the program will never advance past the sleep command until a key is pressed.


---------------------------------------
' $CONSOLE:ONLY
' _DEST _CONSOLE: _SOURCE _CONSOLE

PRINT "If the SLEEP command is working, then the program should continue"
PRINT "in 5 seconds without any need to press a key...."
PRINT
SLEEP 5
PRINT "If we arrive here <without pressing a key> then SLEEP is working,"
PRINT "otherwise it is not working."
---------------------------------------

I just spent all afternoon looking at this, only to come to a fateful, irrefutable conclusion:  It's simply not going to happen.

To get information from the console, we use the windows ReadConsoleInputA function.  Unlike INKEY$ or _KEYHIT, this function doesn't return blank values to us.  It sits there, patiently waiting, until an user event occurs -- mouse movement, keyboard event, or other such thing.

Think of it as basically the equivalent of this:

Code: [Select]
PRINT "TimeStart:"; TIME$
FakeSleep 2
PRINT "TimeStop :"; TIME$

SUB FakeSleep (Time AS _FLOAT)
    DIM ExitTime AS _FLOAT
    ExitTime = TIMER + Time
    DO
        a$ = INPUT$(1)
        PRINT "Time in Loop: "; TIMER - ExitTime
    LOOP UNTIL TIMER > ExitTime
END SUB

The program pauses execution until an event occurs, so it can't just loop back and forth to check the start time against a finish time, and then exit. 

You *have to cause an event* to make it exit the input routine, before you can check the time -- and, if you cause a keyboard event to make it exit the input routine, you're going to exit the sleep routine anyway!

SLEEP used to not work at all for us with the console.  With the changes made to it, it now works, but there's no way the optional TIME counter is going to work with it.  Unless someone can find a way to read from the console, without pausing program execution while waiting for an input event, there's just no way SLEEP is going to work with a timer like that.
Title: Re: A few pushes to the Development build
Post by: Pete on December 05, 2019, 03:42:26 pm
I haven't worked with API stuff in 6+ months, but is this along the lines you would need?

https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-settimer

https://docs.microsoft.com/en-us/windows/win32/winmsg/using-timers

In other words, could that timer API function be turned into a _SLEEPCONSOLE command?

Pete
Title: Re: A few pushes to the Development build
Post by: SMcNeill on December 05, 2019, 03:52:05 pm
It's not a matter of setting a timer; it's a matter of ReadConsoleInput not responding until an event occurs. 

It's a lot like INPUT is in QB64 -- no matter what time event you have going, once the program hits INPUT, it pauses until that input event is over.

SLEEP is a "Pause until a key is hit" type routine, and with the console, ReadConsoleInput is a command that "pauses everything until an input event occurs." 

If we exit ReadConsoleInput, we're going to exit SLEEP as well.
Title: Re: A few pushes to the Development build
Post by: Pete on December 05, 2019, 05:16:55 pm
Well then that would mean re-writing a flow-through routine to replace ReadConsoleInput. That seems like a handful. I recall when I was writing some C programs much earlier in the year, I had to keep dodging statements that would pause for input. Well, good luck with it, but if it helps, I'm in agreement that it doesn't appear to be worth the trouble, and certainly is not a priority.

Thanks,

Pete
Title: Re: A few pushes to the Development build
Post by: hanness on December 05, 2019, 09:09:29 pm
Thanks greatly for looking into this. I can certainly accept the limitations noted. You may just want to put a note in the help for sleep to that effect.

Thanks again for looking into it.



Title: Re: A few pushes to the Development build
Post by: Ed Davis on December 05, 2019, 09:16:59 pm
It's not a matter of setting a timer; it's a matter of ReadConsoleInput not responding until an event occurs. 

It's a lot like INPUT is in QB64 -- no matter what time event you have going, once the program hits INPUT, it pauses until that input event is over.

SLEEP is a "Pause until a key is hit" type routine, and with the console, ReadConsoleInput is a command that "pauses everything until an input event occurs." 

If we exit ReadConsoleInput, we're going to exit SLEEP as well.

I had the same problem (needing a non-blocking ReadConsoleInput()) in a Console program I was writing.  The solutions was the WaitForSingleObject() function.  For instance:

Code: [Select]
// con_in is a handle to the console input buffer
// wait is the maximum number of milliseconds to wait for a key, mouse or other input event
if (WaitForSingleObject(con_in, wait) == WAIT_OBJECT_0) {
  // there is data, read it - could be keyboard, mouse or other console events
} else {
  // no events on con_in, or the wait period expired, go do something else for a while
}

There are various other returns from WaitForSingleObject().  See the Win32 documentation for details.
Title: Re: A few pushes to the Development build
Post by: SMcNeill on December 05, 2019, 09:30:37 pm
I had the same problem (needing a non-blocking ReadConsoleInput()) in a Console program I was writing.  The solutions was the WaitForSingleObject() function.  For instance:

Code: [Select]
// con_in is a handle to the console input buffer
// wait is the maximum number of milliseconds to wait for a key, mouse or other input event
if (WaitForSingleObject(con_in, wait) == WAIT_OBJECT_0) {
  // there is data, read it - could be keyboard, mouse or other console events
} else {
  // no events on con_in, or the wait period expired, go do something else for a while
}

There are various other returns from WaitForSingleObject().  See the Win32 documentation for details.

I’ll definitely check into this.  Many thanks for bringing it to my attention!
Title: Re: A few pushes to the Development build
Post by: SMcNeill on December 06, 2019, 10:22:37 am
With Ed's advice and some experimention of my own, I think I've sorted out the issue with SLEEP in the console not working with any timer.

Before I push any changes into the repo, I'd appreciate it if a few people with the latest development build would give these changes a test run.

Steps for testing:
1) Have the latest Dev build.
2) In internal/c, rename libqb.cpp to libqb.bak to back up the original file, if you want to.
3) Download the libqb.cpp below.
4) Paste it into internal/c.
5) Run the purge_libqb_only.bat file so QB64 will rebuild its needed library automatically.

Now, feel free to run QB64.exe and test all sorts of things out with SLEEP in the console.

A simple test to see if it times out around the time we'd expect:
Code: [Select]
$CONSOLE:ONLY
_DEST _CONSOLE: _SOURCE _CONSOLE

PRINT "Foo"

t# = TIMER
SLEEP 2
PRINT USING "##.### seconds"; TIMER - t#

A simple test to see if it still works without a timer:
Code: [Select]
$CONSOLE:ONLY
_DEST _CONSOLE: _SOURCE _CONSOLE

PRINT "Foo"

SLEEP

The code which pertains to all this working for us, is this: 
Code: C++: [Select]
  1.         #ifdef QB64_WINDOWS
  2.  
  3.             if (read_page->console){
  4.                 int32 junk=0,junk2=0;
  5.                 DWORD dwRet;
  6.                 HANDLE hStdin = GetStdHandle (STD_INPUT_HANDLE);
  7.                 FlushConsoleInputBuffer(hStdin);
  8.                 if (passed){
  9.                             do{
  10.                                 now=GetTicks();
  11.                                 if (now<prev)return;//value looped?
  12.                                 elapsed=now-prev;//elapsed time since prev
  13.                                 ms = ms-elapsed;
  14.                                 prev=now;
  15.                                 dwRet = WaitForSingleObject(hStdin,ms); //this should provide our pause
  16.                                 if (dwRet==WAIT_TIMEOUT)return; //and if we timeout without any input, we exit early.
  17.                                 if (dwRet==WAIT_OBJECT_0){//this says the console had input
  18.                                     junk=func__getconsoleinput();
  19.                                     if(junk==1){//this is a valid keyboard event.  Let's exit SLEEP in the console.
  20.                                         Sleep(100);//Give the user time to remove their finger from the key, before clearing the buffer.
  21.                                         FlushConsoleInputBuffer(hStdin);//flush the keyboard buffer after, so we don't leave stray events to be processed (such as key up events).
  22.                                         return;
  23.                                     }else{//we had an input event such as the mouse.  Ignore it and clear the buffer so we don't keep responding to mouse inputs
  24.                                         FlushConsoleInputBuffer(hStdin);
  25.                                     }
  26.                                 }
  27.                             }while(ms>0);//as long as our timer hasn't expired, we continue to run the loop and countdown the time remaining
  28.                             return; //if we get here, something odd happened.  We should expire automatically with the WAIT_TIMEOUT event before this occurs.
  29.                 }
  30.                 do{ //ignore all console input unless it's a keydown event
  31.                     junk=func__getconsoleinput();
  32.                 }while(junk!=1); //only when junk = 1 do we have a keyboard event
  33.                 Sleep(100); //Give the user time to remove their finger from the key, before clearing the buffer.
  34.                 FlushConsoleInputBuffer(hStdin); //and flush the keyboard buffer after, so we don't leave stray events to be processed.
  35.             }
  36.         #endif

Notice how it flushes the console input buffers after we exit SLEEP -- this is intention and not a bug/glitch.  If we don't clear those buffers, the KEY UP event will remain in them and carry over to the next read of our code, causing us issues.

For now, I've automatically set a delay of 1/10th of a second for someone to lift their finger off the key after pressing it down, and that seems more than sufficient from testing on my machine.  If you run the code on your PC, and it instantly goes to SYSTEM instead of "PRESS <ANY KEY> TO END", at the end of the two sample codes above, speak up and I can up that delay a bit more.

_KEYCLEAR has also been fixed so that it now also clears the console input buffer for us, so IF you end up going straight to system with the console program closing as soon as you press a key, you can always try to add a manual delay and flush that buffer so it won't carry over, such as:

Code: [Select]
SLEEP
_DELAY .2 //time to lift the finger off the key we hit
_KEYCLEAR //and then clear the buffer
END //so the up key doesn't break the END event.



Test it out, report results, and if all goes well, I'll push the changes into the repo and SLEEP will now work inside the windows console with a timed event.  (As well as adding functionality so that _KEYCLEAR will now work to clear the console buffer also.)

Title: Re: A few pushes to the Development build
Post by: hanness on December 06, 2019, 02:49:08 pm
Using your first sample code there is a problem. To best illustrate, I'm adding a single line of code at the end so that you end up with this:


$CONSOLE:ONLY
_DEST _CONSOLE: _SOURCE _CONSOLE

PRINT "Foo"

t# = TIMER
SLEEP 2
PRINT USING "##.### seconds"; TIMER - t#
INPUT "Enter some text: ", Text$


If allowed to run with no user input, it runs just fine. However, if you press a key during the 2 second pause the program advances as expected without waiting for the 2 seconds, but when it reaches the input statement note that as you try to type you see no characters displayed. You have to press ENTER twice to get past the input statement.

I experience the same problem with the second sample where I again add the input statement:

$CONSOLE:ONLY
_DEST _CONSOLE: _SOURCE _CONSOLE

PRINT "Foo"

SLEEP
INPUT "Enter some text: ", Text$

Title: Re: A few pushes to the Development build
Post by: SMcNeill on December 06, 2019, 04:09:17 pm
Using your first sample code there is a problem. To best illustrate, I'm adding a single line of code at the end so that you end up with this:


$CONSOLE:ONLY
_DEST _CONSOLE: _SOURCE _CONSOLE

PRINT "Foo"

t# = TIMER
SLEEP 2
PRINT USING "##.### seconds"; TIMER - t#
INPUT "Enter some text: ", Text$

This isn't a glitch introduced with the latest changes to the routine; it was one which was there even before.  I'm digging into it.
Title: Re: A few pushes to the Development build
Post by: SMcNeill on December 06, 2019, 04:49:11 pm
Using your first sample code there is a problem. To best illustrate, I'm adding a single line of code at the end so that you end up with this:


$CONSOLE:ONLY
_DEST _CONSOLE: _SOURCE _CONSOLE

PRINT "Foo"

t# = TIMER
SLEEP 2
PRINT USING "##.### seconds"; TIMER - t#
INPUT "Enter some text: ", Text$


If allowed to run with no user input, it runs just fine. However, if you press a key during the 2 second pause the program advances as expected without waiting for the 2 seconds, but when it reaches the input statement note that as you try to type you see no characters displayed. You have to press ENTER twice to get past the input statement.

I experience the same problem with the second sample where I again add the input statement:

$CONSOLE:ONLY
_DEST _CONSOLE: _SOURCE _CONSOLE

PRINT "Foo"

SLEEP
INPUT "Enter some text: ", Text$

This glitch here is a screen flag setting.

For whatever reason, QB64 doesn't initially enable our window to work with mouse input.  Since mouse support is something I added when I added the single character input routines, I had to go in and enable it for us, which was done via this little snippet:

Code: [Select]
        fdwMode = ENABLE_EXTENDED_FLAGS;
        SetConsoleMode(hStdin, fdwMode);
        fdwMode = ENABLE_WINDOW_INPUT | ENABLE_MOUSE_INPUT;
        SetConsoleMode(hStdin, fdwMode);

Basically, tell the console that I wanted window input and mouse input...

BUT, the problem was, I wasn't accounting for the flags which were normally set for the console window (like ENABLE_ECHO_INPUT).  When you called the single key routine, permissions with the window were changed, and it wouldn't echo text back on it anymore...

Fix to this appears to be rather simple..ish:

Code: [Select]
        GetConsoleMode(hStdin, (LPDWORD)&dwMode);
        fdwMode = ENABLE_EXTENDED_FLAGS;
        SetConsoleMode(hStdin, fdwMode);
        fdwMode = dwMode | ENABLE_WINDOW_INPUT | ENABLE_MOUSE_INPUT;
        SetConsoleMode(hStdin, fdwMode);

Get the old console flags, use them as the standard base of flags for the screen, and enable the mouse input with them....

Initial testing shows that things appear to be working without any glitches, but I wouldn't swear to it without further testing.

Grab the libqb.cpp below, follow the instructions with the previous post to place it and purge the old library, and test the heck out of it.  Any glitches found now are ones which I won't have to try and address later, after I've forgotten exactly what the heck I've done so far with the source...

As far as I can tell, everything passes muster -- mouse input, single character input, INPUT$, and SLEEP.  If something is off, just let me know and I'll see about addressing it and correcting the problem.
Title: Re: A few pushes to the Development build
Post by: hanness on December 06, 2019, 09:29:24 pm
I've done some quick initial testing, and so far, so good. I'm going to test more extensively but it may be tomorrow before I have opportunity to do so.
Title: Re: A few pushes to the Development build
Post by: SMcNeill on December 07, 2019, 08:58:30 am
Pushed the changes to SLEEP into the development build.  You should now be able to use it in the console along with a TIME limit -- many thanks to Ed Davis for helping show me the command I need to accomplish this! 

Also added functionality for _KEYCLEAR to work with regards to Windows Console, so you can now use it to flush the input buffer.  One thing to note here:  The console input buffer contains *ALL* input which the system has for the console.  When you _KEYCLEAR the buffer, you're also going to clear the mouse buffer as well, as they're inevitably one and the same.  I don't think it'll actually affect anything for folks using it, but I felt it was better to mention this quick of usage than to not mention it.  If it ever does seem like you're losing mouse input events, it may be because you have a _KEYCLEAR command in your mouse handling loop -- and I don't think that'll work as intended at all for you!

The console isn't set up quite the same as our normal screen is, and the mouse and keyboard are irreversibly linked together.    When we read input events, we read both the mouse and keyboard together.  (Which is why we need to call _CONSOLEINPUT to see what type of input we're getting -- mouse, keyboard, or something else oddish.)  By the same token, when we clear one buffer, we're also going to clear the other.

Just be aware of this slight difference with _KEYCLEAR and the console input buffer.  ;)
Title: Re: A few pushes to the Development build
Post by: RhoSigma on December 07, 2019, 04:55:04 pm
Any work done on the &B prefix stuff mentioned here ?
https://www.qb64.org/forum/index.php?topic=1933.msg111816#msg111816

If not, I could do it. Just finished and tested the necessary changes within my old SDL version, but when looking on the same routines in the current version it seem they haven't changed since the old SDL days, so I could easily transfer it and then make a commit/pull request to/from my repo.

Just let me know, if Im not to late and the work is already done maybe.
Title: Re: A few pushes to the Development build
Post by: FellippeHeitor on December 07, 2019, 04:56:13 pm
Hasn’t been done yet. Please add the pull request.

Make sure to work on the latest dev branch.
Title: Re: A few pushes to the Development build
Post by: RhoSigma on December 07, 2019, 07:21:27 pm
Done, pull request is ready for approval.
Title: Re: A few pushes to the Development build
Post by: FellippeHeitor on December 07, 2019, 07:43:13 pm
Sent a reply.
Title: Re: A few pushes to the Development build
Post by: RhoSigma on December 07, 2019, 08:01:26 pm
Sent a reply.

Did too...
Title: Re: A few pushes to the Development build
Post by: FellippeHeitor on December 08, 2019, 10:06:12 am
PR Merged.
Title: Re: A few pushes to the Development build
Post by: RhoSigma on December 08, 2019, 12:40:41 pm
PR Merged.
Thanks Fellippe,

So to announce this for everybody,
with the dev builts starting from today we have extended the recognition of binary number strings (prefix &B) to the INPUT command and to the  READ/DATA commands.

INPUT "Number:"; num
will allow typing &H, &O, and now also &B numbers at its prompt

INPUT #1, num
will allow reading of &H, &O, and now also &B numbers from files

READ hexNum, decNum, octNum, binNum
DATA &HFF, 255, &O377, &B11111111
will now work as expected and without throwing a "Syntax Error" on the binary number

Of course, the case of the H/O/B letters doesn't matter.
This addition completes the support for &B usage, which was already introduced a while ago for the VAL function.

As a remainder for those, who didn't know yet, just as &H/&O, it is also possible to use &B numbers in regular calulations such as X = (34 + &B1101) / &H10 and as arguments for SUB/FUNCTION calls eg. X = Foo(&B1011) or indicies for arrays eg. Num(&B11) = 3. This is the oldest support for &B and was already built into the ancient SDL versions of QB64.
Title: Re: A few pushes to the Development build
Post by: SMcNeill on December 08, 2019, 12:48:55 pm
Question:  Does the changes affect LINE INPUT as well?
Title: Re: A few pushes to the Development build
Post by: RhoSigma on December 08, 2019, 12:58:21 pm
Question:  Does the changes affect LINE INPUT as well?

No it doesn't, LINE INPUT allows for string variables only, hence it doesn't need to do any internal string/number conversion, it just reads a string as is. If you want a number, then you've to pass the input string variable thru VAL() after the input.
Title: Re: A few pushes to the Development build
Post by: FellippeHeitor on December 08, 2019, 01:28:47 pm
As per the wiki.
Title: Re: A few pushes to the Development build
Post by: RhoSigma on December 11, 2019, 02:20:52 am
Pushed an option into the IDE today so you can toggle to Ignore Warnings on and off.   (Variable not defined, or CONST name already in use warnings.)

Either I got this wrong or it doesn't work as it should.
Even with the "Ignore Warnings" option enabled I get the warnings and the code don't get auto-formatted and I'm not able to run(F5)/compile(F11) the program until either commenting the OPTION _EXPLICIT line or add a DIM for the variable.

EDIT:
And why does changing the "Show Compilation Errors Immediately" or "Ignore Warnings" toggle also set the state of the currently loaded program to "changed"? (it gets the * added to its title, and the IDE will ask you to save when quiting).
Title: Re: A few pushes to the Development build
Post by: SMcNeill on December 11, 2019, 03:48:33 am
OPTION _EXPLICIT isn’t tossing you a warning; it throws you a full-fledged ERROR which you can’t ignore.

Try something simple like:

Code: [Select]
DIM foo AS LONG
By itself, that single line with toss you a warning — “Variable not used”, or some such.  You can still compile with the warning; it’s not a full fledged ERROR after all; but still, I find it annoying as the expected “OK” no longer shows up in the IDE.

Personally, I think OPTION _EXPLICT should toss warnings instead of errors, but that’s not how it was designed.  And, since I’m not one to use it at all, I’ll leave it to others to decide what’s the actual best behavior for it.  LET, CALL, OPTION BASE, OPTION _EXPLICIT, REM....  There’s a ton of commands in the language that I never use, and I figure if any of them needs changing, it’s probably best if the people who actually use them changes them.  ;)
Title: Re: A few pushes to the Development build
Post by: RhoSigma on December 11, 2019, 04:03:27 am
Ah, then I got this wrong, I thought it could workaround the requirements imposed by OPTION _EXPLICIT.
Thanks
Title: Re: A few pushes to the Development build
Post by: Bert22306 on December 12, 2019, 04:53:59 pm
Okay, so this binary operations addition, in the latest development build, is one very much appreciated new feature, which I sorely missed before. In the past, I had to go back to basics, when entering binary strings. I've been testing the new features out, and was pleased to see that we can enter binary numbers like this:

num = &B11110000

which works fine.

Or as string variables

binstring$ = "11110000"

which we can then decode as a decimal by doing

bindecconv = VAL("&b" + binstring$)

So far, so good. And, since the LEN of string variables can easily be determined, you should then be able to scale that binary number, if it's a fixed point. Cool.

What I can't seem to do, is what one can do in hex. Which is, how to create the binary number from a decimal input value. As in

HexNum$ = HEX$(dec)

Granted, that last one assumes the hex number is an integer (rounding any decimal fraction), although interestingly enough, you can enter a negative decimal and it assumes a 16-bit two's complement. I attempted this

BinNum$ = BIN$(dec)

No dice. Was this intentional? In theory, I was thinking, could be done much as the hex operation, also assuming integer and perhaps two's complement, 16-bit, for negative decimals? Just wondering. Obviously, we can work around that. Thanks again!
Title: Re: A few pushes to the Development build
Post by: bplus on December 12, 2019, 04:58:56 pm
Hi Bert,

BIN$ is not in QB64 which is why I had it in my toolbox. To add BIN$ to QB64 it might have to be called _BIN$ and who wants that?
Title: Re: A few pushes to the Development build
Post by: Bert22306 on December 12, 2019, 06:08:01 pm
To add BIN$ to QB64 it might have to be called _BIN$ and who wants that?

:)

Well, Clippy wouldn't want that, for sure! Me, I've never objected to _. Although now that you mentioned it, I should have tried that _BIN$, before giving up! Thanks bplus!
Title: Re: A few pushes to the Development build
Post by: RhoSigma on December 13, 2019, 03:17:56 pm
Hi Bert22306 and anyone else,

as I'am responsible for the latest changes regarding &B prefixed binary number strings (https://www.qb64.org/forum/index.php?topic=1933.msg111935#msg111935), it should be probably me too, who provides a appropriate function to do the opposite conversion from any given hex/oct/dec number to binary string.

Although there are already many approaches for a BIN$ function in the Forum, some of my own, some from bplus and Steve McNeill and probably others, I felt there should be one, which best mimics the regular behavior and results of the built-in HEX$ and OCT$ functions, rather than focusing on speed or extended flexibility.

So here it is:

Although not focused on super speed, I just used simple operations and so this BIN$ function is still pretty fast.

Code: QB64: [Select]
  1. 'some average speeds I've measured for this BIN$ function:
  2. '-----------------------+--------------------+--------------------+--------------------
  3. '         CPU           |   QB64 v1.3 x64    |   QB64 v1.3 x86    | QB64 v0.954 (SDL)
  4. '-----------------------+--------------------+--------------------+--------------------
  5. ' Core i5-2430M @2.4GHz |  820000 LONGs/sec. |  620000 LONGs/sec. |  650000 LONGs/sec.
  6. '-----------------------+--------------------+--------------------+--------------------
  7. ' Xeon E-2174G  @3.8GHz | 1650000 LONGs/sec. | 1130000 LONGs/sec. | 1140000 LONGs/sec.
  8. '-----------------------+--------------------+--------------------+--------------------
  9.  

And finally the function:

Code: QB64: [Select]
  1. '---------------------------------------------------------------------
  2. 'Function:  Convert any given dec/hex/oct number into a binary string.
  3. '           Can handle positive and negative values and works in that
  4. '           similar to the QB64 built-in HEX$ and OCT$ functions.
  5. '
  6. 'Synopsis:  binary$ = BIN$ (value&&)
  7. '
  8. 'Result:    binary$ --> the binary representation string of the given
  9. '                       number without leading zeros for positive values
  10. '                       and either 8/16/32 or 64 chars for negatives,
  11. '                       depending on the input size
  12. '
  13. 'Inputs:    value&& --> the pos./neg. number to convert, may also be
  14. '                       given as &H or &O prefixed value
  15. '
  16. 'Notes:     You may also pass in floating point values, as long as its
  17. '           represented value fits into the _INTEGER64 (&&) input, hence
  18. '           approx. -9.223372036854776E+18 to 9.223372036854776E+18.
  19. '           Different from HEX$ and OCT$, BIN$ won't throw an overflow
  20. '           error, if this range is exceeded, but the result is probably
  21. '           wrong in such a case.
  22. '---------------------------------------------------------------------
  23. FUNCTION BIN$ (value&&)
  24. '--- option _explicit requirements ---
  25. DIM temp~&&, charPos%, highPos%
  26. '--- init ---
  27. temp~&& = value&&
  28. BIN$ = STRING$(64, "0"): charPos% = 64: highPos% = 64
  29. '--- convert ---
  30.     IF (temp~&& AND 1) THEN MID$(BIN$, charPos%, 1) = "1": highPos% = charPos%
  31.     charPos% = charPos% - 1: temp~&& = temp~&& \ 2
  32. LOOP UNTIL temp~&& = 0
  33. '--- adjust negative size ---
  34. IF value&& < 0 THEN
  35.     IF -value&& < &HFFFFFFFF~& THEN highPos% = 33
  36.     IF -value&& < &H0000FFFF~& THEN highPos% = 49
  37.     IF -value&& < &H000000FF~& THEN highPos% = 57
  38.     IF -value&& < &H00000000~& THEN highPos% = 1
  39. '--- set result ---
  40. BIN$ = MID$(BIN$, highPos%)
  41.  
Title: Re: A few pushes to the Development build
Post by: Bert22306 on December 13, 2019, 03:50:29 pm
Nice, RhoSigma! I'll be using this. Many thanks.
Title: Re: A few pushes to the Development build
Post by: Qwerkey on December 15, 2019, 12:07:55 pm
If a new stable version (1.4?) is coming up for release, this is what I'd ask for (I think that I'm in a minority of one):  we've discussed elsewhere (https://www.qb64.org/forum/index.php?topic=1577.msg107972#msg107972 (https://www.qb64.org/forum/index.php?topic=1577.msg107972#msg107972), https://www.qb64.org/forum/index.php?topic=1531.msg107516#msg107516 (https://www.qb64.org/forum/index.php?topic=1531.msg107516#msg107516), https://www.qb64.org/forum/index.php?topic=1531.0 (https://www.qb64.org/forum/index.php?topic=1531.0)) that when a FUNCTION is called, it modifies the calling argument (By Reference) by default.

For y = f(x), I still hate the x being changed when you want a function of x.  So, I'd like FUNCTION to always be By Value (argument unchanged) by default.

Ah well, I know that it's not going to happen, but I'm asking anyway.  It came to my attention again in a recent project where I had something like:

A = funct(A), where funct is a FUNCTION which alters A, but A in the lines of funct code is not altered.  So you have the seemingly daft line A = funct(A) which says A is altered by funct, but the By Reference says A is not altered.

This horse is dead, but I'm flogging it anyway!
Title: Re: A few pushes to the Development build
Post by: FellippeHeitor on December 15, 2019, 01:24:05 pm
The only reason stopping that from happening is that the default behaviour in our mother language, QuickBASIC 4.5, is to pass by reference.

If a function is to have its parameters protected by default, but still needs to do any operations on them, it's safer to copy their values at the beginning.

Code: QB64: [Select]
  1. function myFunc(temp_parameter)
  2.     parameter = temp_parameter
  3.     '(rest of code here)
Title: Re: A few pushes to the Development build
Post by: RhoSigma on December 17, 2019, 03:40:44 am
Added a small fix (one line) to the BIN$ function here https://www.qb64.org/forum/index.php?topic=1933.msg112096#msg112096 to make sure that even the lowest possible negative _INTEGER64 number (-9.223.372.036.854.775.808) is correctly returned as 64 bits/chars, instead of 8 bits/chars only and just containing zeros.

Also added some documentation.