OS: win7 ultimate x64 works with x32 compiled exe. When x64 compiler coming out?! good luck with the project!
Printable View
OS: win7 ultimate x64 works with x32 compiled exe. When x64 compiler coming out?! good luck with the project!
Thanks for that, that is good news. Next on our agenda is sorting out the global variables support, and the late-binding of twinBASIC classes (IDispatch). After that, we will get to work on the changes for the x64 linker. We are certainly talking weeks, not years :)
Very good job, it works perfectly.
My support for this great project.
regards
Can TwinBasic open an existing .vbp file? I want to test Twin without downloading project files in an unknown format. I'm on Windows 10 latest updates. Thanks.
Here is an outline of how to debug code in twinBASIC...
Debugging code in twinBASIC
Wayne,
Congrats for this milestone.
I think there is enough room for our projects and they could live side by side.
We talked before and we are kind each other :)
Nice to see some extra information happening. I have contacted some programmers from the old PlanetVB site. They are eager to play around with the preview release. Hopefully TwinBasic eventuates into a replacement for VB6 and more. I sort of would like to see a few more examples of programs made with TwinBasic, but I guess the program still needs to be further developed.
I did a first simple test with TwinBasic with this code, using ADODB to make a query to an Access DB
And the result is good, even error handlingCode:Module TestADODB_Module
' This project type is set to 'Standard EXE' in the Settings file, so you need a Main() subroutine to run when the EXE is started.
Public Sub Main()
MsgBox ("Test ADODB" & vbcrlf & TestDB(),vbInformation+vbYesNoCancel)
End Sub
Public Function TestDB() as string
dim sConnection as string
sConnection = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=D:\Twinbasic\test\test.mdb"
Return GetFieldFromID(sConnection, 1, "Products", "ProductName")
end Function
Public Function GetFieldFromID(sConnection as String, nID As Long, sTableName As String, sReturnField As String, Optional sFieldID As String = "ID", Optional sDefault As String) As String
' #VBIDEUtilsERROR#
On Error GoTo ERROR_getFieldFromID
Dim sSQL As String
Dim oRecord As ADODB.Recordset
Dim aRecords As Variant
sSQL = "Select Top 1 " & sReturnField & " From " & sTableName & " Where "
sSQL = sSQL & sFieldID & " = " & nID
Debug.Print sSQL
Set oRecord = New ADODB.Recordset
oRecord.Open sSQL, sConnection, adOpenForwardOnly, adLockReadOnly
aRecords = oRecord.GetRows()
If UBound(aRecords, 2) > -1 Then
GetFieldFromID = aRecords(0, 0)
Else
GetFieldFromID = IIf(IsMissing(sDefault), vbNullString, sDefault)
End If
EXIT_getFieldFromID:
On Error Resume Next
oRecord.Close
Set oRecord = Nothing
Erase aRecords
Exit Function
' #VBIDEUtilsERROR#
ERROR_getFieldFromID:
Debug.print Err.Description
Resume EXIT_getFieldFromID
End Function
End Module
I had to do some modifications to the code.
So it seems a good start, but not yet any GUI
NB : I had to disable Kaspersky to make VSCode opening Twinbasic project.
I need to investigate the reason
Thanks for trying out twinBASIC, @Thierry69!
With regards to the Kaspersky problem, it will be our compiler EXE triggering it. The file usually sits in the following folder:
C:\Users\{UserName}\.vscode\extensions\twinbasic.twinbasic-0.9.****\out\bin (where **** is the version number installed)
You may need to create an exception rule in Kaspsersky for now. Soon, we will be code-signing the compiler EXE, and this should help increase the reputation of the file over time, and then this problem should resolve.
There is a new release of twinBASIC, v0.9.1537.
It should update automatically.
See the Extensions view (button on left of screen, or View>Extensions from the menu).
You may need to restart if you have an older version.
Here is an article about creating an ActiveX DLL in twinBASIC
Creating a twinBASIC ActiveX DLL
You're right, please copy the helloworld project, and adjust as you need. Apologies, I know it's a pain at the moment in the preview.
If you rename the helloworld files, just note that the code-workspace and twinproj files need to be named identically for now (...except for the file extension of course).
Cloning sample Std-EXE it seems I cannot add second source file for some reason, neither under Sources node, nor under a sub-folder I successfully made under it
https://www.vbforums.com/images/ieimages/2021/04/7.png
cheers,
</wqw>
Yes, this limitation is noted in the preview notes: https://www.twinbasic.com/preview.html
You can add as many components as you like to the single source file though. Sorry about that.
Hey, no problem, I'm sure this will eventually work. I'll be putting everything in *the* single source file for now.
Btw, just read the list with limitations and couldn't find anything about multiple source files -- at least the bullet with this is not obvious to me.
cheers,
</wqw>
Are Consts at module level still disabled like in
This fails with "syntax error. no handler for this symbol" butCode:Class cAsyncSocket
Private Const MODULE_NAME As String = "cAsyncSocket"
End Class
Private MODULE_NAME As String = "cAsyncSocket"
. . . works.
Is this new syntax compiled to a member variable with an initializer?
cheers,
</wqw>
This works in VB6/VBA
Private Declare Function ArrPtr Lib "msvbvm60" Alias "VarPtr" (Ptr() As Any) As Long
Public Sub Main()
Dim arr() As LongEnd Sub
Dim ptr As Long
ptr = ArrPtr(arr)
. . . but fails compiling with TB with "validation of call to 'ArrPtr' failed. argument for 'Ptr': cannot coerce type 'Long()' to [ByRef] 'Any()'"
Changing API declare to Ptr() As Long fixes it but this would require separate API declare for each possible type for array's elements.
This
Class Test
Public Sub Init()End Class
PassThis MeEnd Sub
Public Sub PassThis(oRef As Test)
End Sub
. . . fails with "unable to bind to reference; this is a read-only binder".
Edit: Oh, it needs ByVal oRef As Test -- I get it :-))
cheers,
</wqw>
This
Class Test
Private Property Get Data(ByVal First As Long, Optional ByVal Index As Long) As Long
End Property
Private Property Let Data(ByVal First As Long, Optional ByVal Index As Long, ByVal lValue As Long)
End Property
Public Sub Init()
Data(3) = Data(4)End Sub
End Class
. . . fails with "too few arguments, expected at least 2 in call to 'Data'".
Passing an explicit value for the optional Index parameter fixes it.
Cool!
Unfortunately my cAsyncSocket class is both using With MyUdt / End With in a few places *and* is raising events with RaiseEvent OnReceive (to be usefull for anything) so I'll have to wait a few more weeks to test porting my VNC server (headless and perfect match for TB testing).
cheers,
</wqw>
The "single file concept" can later be quite handy, when it comes to the "publishing" of small or midsized Demos...
(only one file to upload to GitHub or Bitbucket, or to "drag into an Email").
In that regard...
Currently there are two files to "manage" a project:
- ProjectName.code-workspace
- ProjectName.twinproj
The *.code-workspace (as a file-ending) is already associated with (VS)Code.exe (containing setting-defs in JSON-format).
Whereas the *.twinproj is not associated with any executable currently...
So, why not ship your VSCode-plugin-binaries with an additional little "TwinStarter.exe",
which after installing the plugin is then already "registered" for the *.twinproj File-endings...
The TwinStarter.exe will then get the chance, to "do a few things with the passed project-file" internally, as e.g.:
- dynamically creating a *.code-workspace-file with the same ProjectName (in case there currently is none in the same folder)
- for that, one could parse out a "leading JSON-header" (instead of the current "binary one")
- and that header should be compatible with the JSON-format which is expected in a "normal *.code-workspace-file"
- to be able to ensure the content of a potentially missing *.code-workspace-file,
- which after that dynamic creation could then be used to start VSCode (indirectly) in turn ...
- simply by calling ShellExecuteW with the *.code-workspace-filepath
So, this new "JSON-header" (instead of the binary header+footer in *.twinproject files),
basically contains the normal JSON-fields which are expected in a *.code-workspace-file,
but also a few "additional JSON-nodes" (as e.g. references to additional "normal *.bas and *.cls files) -
but of course also the informations which formerly sat in the binary header and footer of a *.twinproject.
Ensuring "plain text" in files which contain code - also agrees better with later Repo-Uploads
(to not confuse any "diff-processings" between file-versions).
To conclude - I guess what I was trying to say is - please "empower" the *.twinproject files, making them more universal in:
- not requiring a workspace-file (because the new TwinStarter.exe can ensure that dynamically)
- only containing PlainText in the end (a leading JSON-header instead of the current binary ones)
- codewise keeping their current ability to directly host module- and class-sections as a single-file code-container
- whilst also offering the ability, to act more like a *.vbp (only containing relative references to *.bas and *.cls code-files)
Olaf
Hey Olaf,
Thanks for your thoughts. Ironically, in the early alpha builds we had a single file solution, which was a single code-workspace file that had the project file embedded into a configuration setting BLOB as base64 data (in the JSON file). It worked well for small project files, but it soon became apparent that the code-workspace file wasn't designed to handle large binary data, so we separated out the project file to improve the performance.
I do like your idea, but the problem with using a temporary code-workspace file is that there is potentially no chance to save/propagate changes in the temporary code-workspace file back to the proposed dual-format file. To explain... When VS code informs extensions to cleanup and shutdown, the extensions have very tight restrictions on what they can do, and the time they get to do it in. During testing I noted VSCode extensions get roughly 1 second each to shutdown (sometimes less), and then... poof the extension process is destroyed abruptly -- if you try to save something at that point, you most certainly would end up causing corruption if there's even a small delay. Even executables that are started from the Node.js environment, such as the twinBASIC compiler get terminated abruptly alongside the extension host.
Now it may be that we can come up with a reasonable solution to the above problem, but I'm not convinced it's possible to make it 100% reliable, and that concerns me.
Ideally we'd provide the code-workspace file itself to VSCode via a virtual file system, so that we then get proper control of reading and writing the file. But unfortunately, I had already tried that method early on in development, and VSCode just didn't allow it.
A solution might be to just make the code-workspace file optional, and have a default one created on-demand if you open the twinproj file in VSCode. That way, you can distribute just the twinproj file for simplicity.
The file format for the twinproj file is binary because we allow binary files in the virtual file system, and formats like JSON are not great for binary data. The reason for allowing binary files is because you'll be able to put files (e.g. graphics) into the Resources folder soon, and they will be pushed directly into the built EXE/DLL resources at link time. For source control concerns, we will be offering git integration that works off the virtual file system in-memory, and so the actual binary file format that the project file is stored in won't matter.
Hello, congrats for your achievements!
Since it is intended to have backward compatibility with VB6 I want to ask if there is any technical reason for not sticking to the original file format and system, I mean plain text for definitions and binary files for binary data.
Text files:
vbp
bas
frm
cls
ctl
pag
Binary files:
frx
ctx
pgx
res
(better forget about vbw)
You could add your own new keys and sections on the text files for the new properties and features, or even new text files if needed, and new binary files (and extensions) if needed for whatever new features not supported by the original format.
The developers many times like to edit the files "by hand", but for being able to do that the files need to be easily readable and understable.
That's my opinion (and wishes).
I wish much success to you and also to Carles.
Hi Eduardo,
Thanks for your message. The plan is that all these formats will be supported, and natively.
Think of the twinproj file like a ZIP container, but it will also allow links to external files. So you'll be able to open a VBP file in twinBASIC/VSCode, and that will get migrated to the twinproj format, with links to the individual files (.bas, .cls, etc). The VBP file will be kept in-sync with the new twinproj format, and this will be effectively invisible to the developer.
The .twin file format is naturally different, because there is no way we can represent that in the old VB6 file formats at all, since you can't have multiple components per file, but all the original VB6 file formats will be supported via file links. Just not for this preview :)
Thanks for responding Wayne,
I don't know why you need multiple components per file, what are these components and why they cannot be written all together, the text part into a text file and if they have a binary part into a companion file (as VB6 does).
But I don't know what you are doing. I just have some insights into your project but I still didn't test anything (I've been currently busy with other things, but I'm very interested of course).
Aside from that, in my case the last 10 times that I said something was impossible 9 I was wrong.
But if you say so, it must be.
Regards.
Edit: I mean text files UTF-8 encoded, with some keys Base-64 encoded if necessary.
An article about additional features in the VB6 compatible twinBASIC...
New Syntax in twinBASIC: Part 1
May I make a little suggestion? A compiler option to enforce assignment and equality/inequality (= and ==/!=) syntax, as in C and other languages. I guess it only makes sense by producing an appropriate warning if a "=" is used in a comparison.
No reason other than habit, readability and being able to more easily port C stuff.
I'd appreciate, when at least that will work in the future.
And as for "back-syncing" into the twinbasic-projectfile... (from the dynamically created workspace-file).
If it succeeds, all is well - and the "TwinStarter.exe" could override the "last temporary workspace-file" with it.
If it does not succeed (or was left out) - then "TwinStarter.exe" could use:
- either the last temporary workspace-file
- or if there isn't one yet for the project-file, then dynamically create one with the default-settings
The only binary files which come to my mind, are image-files (or perhaps Font-Files)...
And *especially* these should go into a different, isolated location in the filesystem.
You might want to take a look, how "all kind of resources" *could* be handled
(conveniently, behind a \Res\ SubFolder below the Poject-Path, where you can place anything):
https://www.vbforums.com/showthread....ontainer-Files
According to the above example - what you will end up with - is a single Res.zip file -
which in turn could be "hung in" into the final binary as a "single ByteArray-resource" in a post-compile-step automatically.
I also don't see the "big advantage" of dealing with the "virtual file-structure" you currently have.
...IMO, the Node.js fs-module is capable enough to deal with "normal Files" in a performant manner
(with free choice, to do certain methodcalls synch-, or asynchronously).
And if I read the VSCode-docu correctly - its "workspace" should be able to provide you with
proper "filechange"-events also for normal files.
JFYI - the main-VB6 project at the place where I work, has literally "hundreds" of modules and classes
(when combined in certain Debug-Groups)... meaning "Megabytes of Code" to compile for a debug-run.
I cannot imagine that VSCode will not choke, when such an amount of modules shall be handled in "virtual mode".
And as for the "binary-format" (binary-blocks) on your project-file ...
I'm quite sure I'm not the only one here, who would (quite strongly) prefer "plain-text" for that important "entry-point-into-a-given-project".
Cannot count the times and occasions, where I've written (or used) tools,
which performed different operations on all kind of VB-sourcefiles (without involving the VB6-Executable at all).
Olaf
Yes, that is pretty much what we have planned. We already have the Resources folder in the project virtual file system ready for this. Files in there will be embedded at build time automatically into the PE file resources section, and they will be exposed conveniently through the object model at runtime.
Absolutely, I agree. That wasn't a factor in the decision.
The main reason for the current design is so that we can, in future, support in-memory VBA streams (which are IStorage based). This design is extremely flexible, in allowing for both in-memory streams as well as on-disk files. The further benefit of being able to distribute a simple one-file project solution is also particularly useful.
Oh believe me, VS Code will handle this just fine. The virtual file system is actually implemented within the twinBASIC compiler (written in C++), with VS Code connecting to it via raw socket requests. Believe me, we have extensively tested it, and there is absolutely no performance concern with the scenario you describe.
I have to say how impressed I have been with twinBASIC so far. Good work, Wayne.
Are you planning to publish a roadmap for twinBASIC - when can we expect Forms/GUI support?
Also on my wish list is having compile switches similar to VB. Compile switches from Advanced Microsoft Visual Basics (second edition)
The output of c2 hooked in a default project is:
The output of link is:Code:C3 -il "C:\Users\user\AppData\Local\Temp\VB430308" -f "Form1" -W 3 -Gy -G5 -Gs4096 -dos -Zl -Fo"C:\Users\user\Desktop\Form1.OBJ" -QIfdiv -ML -basic
Is it possible to keep that string format compatible?Code:L1NK "C:\Users\user\Desktop\Form1.OBJ" "C:\Users\user\Desktop\Project1.OBJ" "C:\Program Files (x86)\Microsoft Visual Studio\VB98\VBAEXE6.LIB" /ENTRY:__vbaS /OUT:"C:\Users\user\Desktop\Project1.exe" /BASE:0x400000 /SUBSYSTEM:WINDOWS,4.0 /VERSION:1.0 /INCREMENTAL:NO /OPT:REF /MERGE:.rdata=.text /IGNORE:4078
Articles about additional features in the VB6 compatible twinBASIC,
including AndAlso, OrElse, Continue For and Return.
These are additions to the VB6-compatible language and may be familiar to VB.Net users.
New syntax in twinBASIC part 1
New syntax in twinBASIC part 2
New syntax in twinBASIC part 3
The new ternary If operator is a missed opportunity for this to compile in TB
Dim a As Variant, b As Variant
If(True, a, b) = 10
The point is that in C/C++ the ternary operator preserves value category (here being l-value) so that the analogous snippet works just ok.
In C/C++ this (expr ? a : b) is replaced by something like *(expr ? &a : &b) so that ternary operator works even with struct member access like this snippet
MyStruct a, b;
(true ? a : b).MyField = 5;
cheers,
</wqw>
The sample is contrived but it's used in C/C++ so it must be of some use to somebody. (To me for instance.)
The False part is not evaluated in C/C++ as well and there are no non-short-circuit logical operators in C/C++ like the And/Or debacle in VB6. Not sure there is any other language lacking short-circuit operators like VB6 to be honest. Probably only VB5. . .
cheers,
</wqw>
About the ternary that you propose, I can't think where I would need that.
Also, in VB6 it can be done like this:
But the other one, could have some uses IMO:Code:If condition Then a = 10 Else b = 10
Code:FontName = If(nFont is Nothing, "Arial", nFont.Name)
I tested twinBasic and it is really exciting.
It's of course a good thing to see that twinBasic has added some new language features. But I'm thinking about a question:
twinBasic has its own Basic language features (mainly similar to VB.NET), then Olaf's VB.Next will also have its own Basic language features, and RadBasic will also have its own Basic language features.
If this is the case, then the Basic code accepted by these three compilers cannot be unified. Maybe we should have a Basic standardization organization like ECMAScript.
I'll be happy to consider the syntax suggested by @wqweto, though I do wonder how many developers would actually use that form. I'll be creating a github repo just for issue tracking and feature requests in the next day or so. Once we've got that set up, I would ask that you post your suggestion over there, and then others can comment on it before we make a decision.
BTW, twinBASIC already supports the ternary short-circuiting If() operator function in expressions.
Thanks for all the support / suggestions / bug reports so far! Much appreciated.
twinBASIC issue tracking is now live at github. We've been inundated with bug reports and feature requests from many different sources. Going forward, it would help immensely if you could report bugs and post feature requests over at the repository which will help us better keep track and manage requests.
https://github.com/WaynePhillipsEA/twinbasic
https://github.com/WaynePhillipsEA/twinbasic/issues
Tomorrow we'll put up all the existing known issues as currently listed on the main website. Thanks!
I actually use even VBs current IIF() kinda like that with objects
(often when filtering into "two different baskets" like the code below shows):
Prints out:Code:Private Sub Form_Load()
Dim Num, Evn As New Collection, Odd As New Collection
For Num = 0 To 9
IIf(Num Mod 2, Odd, Evn).Add Num
Next
Debug.Print vbLf; "Even Numbers: ";
For Each Num In Evn: Debug.Print Num;: Next
Debug.Print vbLf; "Odd Numbers: ";
For Each Num In Odd: Debug.Print Num;: Next
End Sub
If there's more than two different "target-objects" to decide between... the Choose()-function can be used in a quite similar manner.Code:Even Numbers: 0 2 4 6 8
Odd Numbers: 1 3 5 7 9
Olaf
But surely that would help standardise and potentially reduce the number of those variants? It also makes it much easier for any developer as you can re-use the documentation and testing methodology for any version of basic following the standard. No need to rewrite the book.
A developer I know wasted huge amounts of time developing an IDE, a forms developer, a whole development environment only to fall at the last fence because he failed to understand the advantages of maintaining compatibility with the product that came before. Developers are generally bad at documentation. He did not realise that if he stood on the shoulders of giants he was much more likely to succeed. As it was, he went on a slightly different technical route which could not take advantage of all that had been achieved thus far in the past 5 years. His product was 90% complete, in parts it was very good - it failed despite that as it had no documentation, was incompatible, migration was difficult due to the technical differences and due to the massive workload he had taken on (due to the technical differences) he was unable to produce a bug free and usable product.
A BASIC standard along the ECMA methodology would be a very desirable thing to have and simply following VB6 in all its peculiarities would mean one step toward that - no one would need to be retrained and all existing documentation and sample code/bug fixing would apply. Yet-Another-BASIC-Variant is not what we need and I applaud RADBasic in that developer's efforts to attain this or at least have it as his goal.
This was the IDE that failed. You click on the program running on your desktop, click EDIT. Full transparency of all objects, use of VBscript or .js as you desired.
https://www.vbforums.com/images/ieimages/2021/04/10.png
It was good, at least this bit was. Closed source, dead and gone forever, no more development because he forgot what benefits standardisation brings and how compatibility is vital.
If TwinBasic claims to be VBA/VB6 compatible at the end than this is "enough standards" and all pluses what come on top does not need to be synced with other basic variants. IMO